I wanted to clarify my understanding of the following ways of defining a function.
f(x) = …
f(x::T) where {T} = …
f(x::Any) = …
Is it true that 1. and 2. are equivalent if there are no type restrictions in the UnionAll? That is, the function is specialized for every different concrete input type.
Is it true that 3. is never specialized for a concrete type, but it is executed as if its argument is of type Any? I imagine this is important if one wants to limit excessive specializations for functions which do not benefit from it much.
There is no difference between those three, except that in 2. the type parameter T will be available inside the function body (you can anyway get that by calling T = typeof(x) later on.)
Each will be specialized every time. In order to avoid specialization, you can look at @nospecialize: Essentials · The Julia Language