'How to write a macro whose body contains a user defined symbol?

I intend to create a macro that has the following behaviour:

@pass_symbol sym func

Expands to:

func(:sym)

The following experiments didn't yield any results:

macro pass_symbol(symarg, funcarg) 
    quote 
         $funcarg($symarg)
         # turns into `func(sym)`
         # which results in an error 
         # as `sym` is not defined
    end
end

macro pass_symbol(symarg, funcarg) 
    quote 
         # combinations of
         $funcarg($(Symbol(symarg)))
         # or
         $funcarg(Symbol(symarg))
         # turns into `func(Symbol(sym))`
         # which for the same reason detailed 
         # above results in an error
    end
end

macro pass_symbol(symarg, funcarg)
    quote
        $funcarg(:$symarg)
        # I wished to escape the ":" 
        # so that it would expand into func(:sym) 
        # but it didn't manage to
        # evaluate `:` and `$` separately 
    end
end

I tried more shenanigans for sure. Eventually, I found this one:

macro pass_symbol(symarg, funcarg)
    str = ":$symarg"
    quote
        $funcarg($(Meta.parse(str)))
    end
end

But I'm not happy about it, as I feel like there must be a more idiomatic way to achieve this.

Please, feel free to suggest a more suiting title, as I couldn't find anything related using google and I want this to have good search-ability.



Solution 1:[1]

macro pass_symbol(symarg, funcarg)
    quote
        $funcarg($(Expr(:quote, (symarg))))
    end
end

Or more concisely:

macro pass_symbol(symarg, funcarg)
    quote
        $funcarg($(QuoteNode(symarg)))
    end
end

But I'm still not sure why QuoteNode achieves the desired behaviour following the documentation:

A quoted piece of code, that does not support interpolation. See the manual section about QuoteNodes for details.

Or if there's a way to solve this issue: $funcarg(:$symarg)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1