'Create a local variable with a given name from within a macro?

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

@deffunc f x x+x

Expands to:

f(x) = x+x

And properly adds a function with the given name, in this case f, to the scope where the macro is called.

After reading about macros and searching for similarly related questions I just couldn't find a way to achieve this without having to escape the whole attribution itself, and therefor, the whole macro:

macro deffunc(fname, arg, body)
    e = quote
        $fname($arg) = $body
    end
    esc(e)
end

But escaping it in its holiness seemed undesirable to me.

I tried to find a better way, like joining quotes but to no avail, then I went around doing so in the following manner:

macro deffunc(fname, arg, body)
    e = quote
        $fname($arg) = $body
    end
    e = esc(e)
    quote
        $e
    end
end

But it's ugly as hell and I feel like I'm missing something simple.



Solution 1:[1]

having to escape the whole attribution itself

Well, I think that's the piece of the puzzle that might have been puzzling you: you don't have to escape the attribution itself to avoid having your variable gensymed.

Instead, you want to escape the symbol by doing:

macro deffunc(fname, arg, body)
    fname = esc(fname) # this returns `$(Expr(:escape, :f))`
    e = quote
        $fname($arg) = $body
    end
end

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 DMeneses