It’s fair to ask for the intended use case. Here it is. It’s a language interpreter.
struct Expr
id, data
end
id is a hundred or so symbols, say :integer, :string, :+, :-, :*, …that is a hundred or so language “lexicons” (I meant to type :slash but it rendered as an frowning icon)
data can be very simple if it is atomic like a number: Expr(:number, 123.4)
or can be recursive, e.g. for addition we will have Expr(:+, )
Expr(:+, (Expr(:integer, 1), Expr(:integer, 2)))
Now to display an Expr as a string we may define a string function:
function Base.string(x::Expr)
if x.id == :integer
string(x.data)
elseif x.id == :something_else
do_something_else(x.data)
elseif ..
... hundreds of these...
end
As the conditions seem to be mutually exclusive, you can try to define a global to build the resulting function AST, then modify it within other files by adding more branches and finally eval it.
Edit:
Or just define a dispatch table as a Dict{Symbol, Any}?
Then it will be
The thing you’re trying to do here is basically what often goes under the name “traits” in Julia. There’s several different packages which facilitate this. Under the hood they basically do something equivalent to @xiaodai’s Val code above, so there’s no getting around the performance issues being discussed, but if performance is not critical, traits can certainly offer a nice syntax / logical organization / allow you or your users to add new cases in a way that would be impossible with a big if-statement.
using Traits
struct Structure
id
end
@traits function p(c::Structure) where {c.id == :x}
"c.id is x"
end
@traits function p(c::Structure) where {c.id == :y}
"c.id is y"
end
julia> p(Structure(:x))
"c.id is x"
julia> p(Structure(:y))
"c.id is y"
julia> p(Structure(:z))
ERROR: MethodError: no method matching p(...)
The nice thing is that the final thing is a MethodError as you might expect, and you’re free to implement it later if you’d like.
Despite the manual warning against over-use of types with values as parameters, it is worth noting (for others searching for this topic) that Julia itself does exactly that for 7 different ways of rounding:
Presumably the benefit there of dispatch over if/elseif is the extensibility.
It’s a clean example for anyone wanting to essentially dispatch on a few Symbols.