I’ve been trying to teach my students traits, only to realize that there is something I don’t fully understand. Is there any different between these two approaches to dispatch?
The second one relies on compiler inlining and constant propagation (which might not happen if the functions become sufficiently complicated), whereas the first only relies on type inference and specialization (which happen even for very complicated functions).
(Technically, even in the first case you are relying on inlining and constant propagation because you are calling Val(true) rather than Val{true}(). But for the Val function with literal constants the two are equivalent these days; this wasn’t the case in early versions of Julia IIRC.)
Thanks!
Follow up: assuming I do call Val{true}() in trait1, is there any difference between using value-types and using dummy structs like TraitSatisfied()?
If you define your own types then you can have a hierarchy with subtypes. (There is also a difference in readability by using more descriptive names, of course.)
With 2 maybe no, but if you have more you can apply the strategy pattern by modifying only one line (see design patterns and best behavior in Julia)
For example
abstract type Algo end
struct Fast:<Algo end
struct Slow:< Algo end
...
struct Experimental<:Algo end
Then you can dispatch multiple versions by simply doing different dispatch of
Func(f::Algo,...)
This is a great pattern if you want to maintain a growing code without awkwards if else switches inside