I have heard julia has dispatch on values for symbols,
and so I use Val{:MySymbol}
.
But this doesn't seem to work:
julia> foo(x) = "other"
foo (generic function with 1 method)
julia> foo(x::Val{:zinger}) = "It was zinger"
foo (generic function with 2 methods)
julia> foo(:zinger)
"other"
Why isn't it outputting "It was zinger"?
Dispatching on values isn't magic. It uses the exact same mechanics as for dispatching on parametric types. So you need to pass in a instance parametric type which has that value as a type parameter if you want to dispatch on it.
In your question Val
is the parametric type -- and it exists just for this kind of thing.
So you need to have written:
julia> foo(Val{:zinger}())
"It was zinger"
If you wanted you could write an overload of foo
to automatically wrap up its arguments into a type parameter
julia> foo(x::Symbol) = foo(Val{x}())
foo (generic function with 3 methods)
julia> foo(:zinger)
"It was zinger"
However, this will cause a dynamic dispatch.
julia> @code_lowered foo(:zinger)
CodeInfo(:(begin
nothing
return (Main.foo)(((Core.apply_type)(Main.Val, x))())
end))
vs the fully realized at compile-time solution:
julia> @code_lowered foo(Val{:zinger}())
CodeInfo(:(begin
nothing
return "It was zinger"
end))