I think the safety thing is a non issue as well - what arguments could you pass in to the statically typed function that would cause the use of dynamic to bite you in the ass?
A dynamic "type" is really just `object` whose methods are looked up at run time. It's not tagged data at all. See [1] for more info, specifically the example(s) at the bottom, as the reflection code is what gets executed at run (albeit with caching so that methods aren't looked up all the time).
`dynamic` is a complex feature that enables multiple dispatch as a side-effect, but only because it allows a whole lot more.
[1]: https://visualstudiomagazine.com/Articles/2011/02/01/Underst...
> what arguments could you pass in to the statically typed function that would cause the use of dynamic to bite you in the ass
public void Output(int value);
public void Output(Person person);
...
dynamic aValue = "Some String";
Output(aValue);
Compiles, because the actual resolving of which overload to call is done at runtime, not at compile time. And at runtime, there is no overload that accepts a string.Dynamically typed languages usually represent objects as something like a struct with an int tag to represent the type, and a void pointer for its value. The actual reflection going on in the code I posted for multiple dispatch would surely be nothing more than an int comparison - same as what Ocaml probably does.
Ah, I misunderstood the question. Yes, in that case it's fairly type-safe.
> The actual reflection going on in the code I posted for multiple dispatch would surely be nothing more than an int comparison
Is this based on gut reaction or are you talking about optimizations that `dynamic` performs? I ask because my understanding is that `dynamic` is like a really efficient reflection-emitter, that attempts to do at runtime the same thing that the compiler would do at compile time, but slower because it has to look stuff up via reflection.
From Eric Lippert [2]:
> The magic is: the compiler emits code that starts the C# compiler again at runtime. The runtime version of the compiler analyzes the call as though the compile-time types of all the objects had been their actual runtime types, generates an expression tree representing that call, compiles the expression tree, caches the delegate for next time, and runs the delegate.
[2]: http://stackoverflow.com/questions/10330805/c-sharp-multiple...
So maybe `dynamic` at runtime figures out that it can do a "a struct with an int tag to represent the type, and a void pointer for its value", but I wouldn't assume it does and from what I've read on it, I wouldn't think that it does.
None if the function is written correctly, but by that logic you don't need type safety at all. The point is that the dynamic technique gives you no warning if you forget to implement one of the cases.
void React(Animal me, Animal other)
{
ReactSpecialization(me as dynamic, other as dynamic);
}
Unless you pass in a casted value here, it's fool proof.