Generic dispatch with Symbols
Asked Answered
Z

1

8

I was wondering if there was a way to use Symbols for multiple dispatch, but also include a "catch-all method". i.e. something like

function dispatchtest{alg<:Symbol}(T::Type{Val{alg}})
  println("This is the generic dispatch. The algorithm is $alg")
end
function dispatchtest(T::Type{Val{:Euler}})
  println("This is for the Euler algorithm!")
end

The second one works and matches what's in the manual, I'm just wondering how you get the first one to work.

Zoon answered 4/9, 2016 at 8:21 Comment(2)
Is dispatch on elements Val(alg) (instead of types Val{alg}) of equal interest?Inure
This isn't of interest anymore. This was DiffEq's first design, but now we use types. These days I'd say it's best to use types since you are going to constrain the choices anyways to write the dispatches. If you do want to use Val, it's probably best to dispatch on the elements in v1.0 since constant prop will kick in an it'll be inferred. So this question is quite a relic of the past.Zoon
A
9

You can do it this way:

julia> function dispatchtest{alg}(::Type{Val{alg}})
           println("This is the generic dispatch. The algorithm is $alg")
       end
dispatchtest (generic function with 1 method)

julia> dispatchtest(alg::Symbol) = dispatchtest(Val{alg})
dispatchtest (generic function with 2 methods)

julia> function dispatchtest(::Type{Val{:Euler}})
           println("This is for the Euler algorithm!")
       end
dispatchtest (generic function with 3 methods)

julia> dispatchtest(:Foo)
This is the generic dispatch. The algorithm is Foo

julia> dispatchtest(:Euler)
This is for the Euler algorithm!
Antimicrobial answered 4/9, 2016 at 8:34 Comment(5)
Note that the performance of this is likely to be less good than just having an if-else statement that checks for specific symbol values, and also slower than looking up symbols in a dictionary, so there's effectively no good use case for this. If you don't need extensibility, use if-else; if you do need extensibility, use a dict.Akin
Could you please provide us with a good use case for value types then? Chris does need the extensibility. Do you mean to use a global Dict instead? That could be a problem with precompilation if I understand correctly.Antimicrobial
How it effects performance really depends on how costly the function is. In my case, the functions are very costly and would it the if-else statement thousands if not tens of thousands of times, where else the price of dispatch is payed once (and it minuscule, measured probably in microseconds in comparison to the minutes / hours of the actual function call). I've found this solution as really helping performance in this case. As always, benchmark for your specific case.Zoon
@Akin if-else is the recommended approach to define getproperty for custom types? Will the branching be elided at compile time (since the compiler knows in principle which symbol was actually used)?Defrayal
Stumbled across this now (years after, v1.9.2), and this was useful. Just to point out that first line "function dispatchtest{alg}(::Type{Val{alg}})" should be changed to "function dispatchtest(::Type{Val{alg}}) where alg" or similar to work.Beluga

© 2022 - 2024 — McMap. All rights reserved.