See the Docs
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))