Retrieve unevaluated symbol inside `@eval`

In one of my packages I use @eval to define a list of functions in a loop based on symbols. I would also like to use the symbol without evaluating it, but I can’t figure out how. Maybe it’s an XY problem?

julia> for s in [:a, :b, :c]
           f = Symbol("f_", s)
           # I want f_a(:a) = true and f_a(any_other_symbol) = false
           @eval $f(x::Symbol) = x == $(Symbol(repr(s)))
       end

julia> f_a(:a)
ERROR: UndefVarError: `:a` not defined

This is because when you do $(Symbol(repr(s))), you are converting :a into the string ":a" (this is what repr() is doing), and when you convert it back to a symbol, it’s a symbol Symbol(":a") and not :a.

Here’s what you’re looking for:

for s in [:a, :b, :c]
    f = Symbol("f_", s)
    @eval $f(x::Symbol) = x == $(QuoteNode(s))
end
4 Likes