# Defining an Anonymous Function in a Macro

**URL:** <https://discourse.julialang.org/t/defining-an-anonymous-function-in-a-macro/92625>\
**Category:** General Usage\
**Tags:** metaprogramming\
**Created:** [January 7, 2023, 5:03am UTC](https://discourse.julialang.org/t/defining-an-anonymous-function-in-a-macro/92625 "2023-01-07T05:03:19Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [January 7, 2023, 5:03am UTC](https://discourse.julialang.org/t/defining-an-anonymous-function-in-a-macro/92625/1 "2023-01-07T05:03:19Z")

</div>

I’m working on a macro that defines several functions that all have the same parameters. However, upon evaluation, the keyword arguments of the functions are getting prefixed with `Main.` as though they are variables that need to be resolved.

MWE:

```julia
"""Produce an anonymous function from a block of instructions and argument names."""
function make_anon_function_expr(function_block; args = (), kwargs = nothing)
    sym_args = Any[Symbol(p) for p in args]
    if !(kwargs isa Nothing)
        pushfirst!(sym_args, Expr(:parameters, (Symbol(k) for k in kwargs)...))
    end

    return Expr(
        Symbol("->"),
        Expr(
            :tuple, 
            sym_args...
        ),
        function_block
    )
end

# Test out make_anon_function_expr
func_block = quote
    return x + y
end

f = make_anon_function_expr(func_block; kwargs = (:x, :y))
eval(f)(;x=3, y=2)
# 5

```

Now with a macro

```julia
macro MakeMyStruct(func_block)
    func = make_anon_function_expr(func_block; kwargs = (:x, :y))
    return func
end

b = @MakeMyStruct begin
    return x + y
end
# ERROR: syntax: invalid keyword argument syntax "Main.x"

```

I’d appreciate your thoughts!

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [January 7, 2023, 5:19am UTC](https://discourse.julialang.org/t/defining-an-anonymous-function-in-a-macro/92625/2 "2023-01-07T05:19:02Z")

</div>

This is a macro hygiene issue. If you use `macroexpand`, you’ll see that it is trying to use the global variables `x` and `y` instead of your new ones:

```plaintext
julia> @macroexpand @MakeMyStruct begin
           return x + y
       end
:((; Main.x, Main.y)->begin
          #= REPL[103]:2 =#
          return Main.x + Main.y
      end)

```

The fix is to use `esc`:

```julia
julia> macro MakeMyStruct(func_block)
           func = make_anon_function_expr(func_block; kwargs = (:x, :y))
           return esc(func)
       end
@MakeMyStruct (macro with 1 method)

julia> @macroexpand @MakeMyStruct begin
           return x + y
       end
:((; x, y)->begin
          #= REPL[105]:2 =#
          return x + y
      end)

julia> b = @MakeMyStruct begin
           return x + y
       end
#67 (generic function with 1 method)

julia> b(; x = 3, y = 2)
5

```

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [January 7, 2023, 5:22am UTC](https://discourse.julialang.org/t/defining-an-anonymous-function-in-a-macro/92625/3 "2023-01-07T05:22:07Z")

</div>

Ah, of course! Seeing it now, seems obvious. Thank you!
