# Escaping expressions within macro calls

**URL:** <https://discourse.julialang.org/t/escaping-expressions-within-macro-calls/46160>\
**Category:** General Usage\
**Created:** [September 6, 2020, 9:22pm UTC](https://discourse.julialang.org/t/escaping-expressions-within-macro-calls/46160 "2020-09-06T21:22:22Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![lucas711642](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lucas711642/32/12051_2.png) [@lucas711642](https://discourse.julialang.org/u/lucas711642)\
**Post date:** [September 6, 2020, 9:22pm UTC](https://discourse.julialang.org/t/escaping-expressions-within-macro-calls/46160/1 "2020-09-06T21:22:22Z")

</div>

```julia
julia> macro macro1(expr)
           esc_expr = esc(expr)
           :($expr, $esc_expr)
       end;

julia> macro macro2(expr)
           esc_expr = esc(expr)
           :(@foo $expr, $esc_expr)
       end;

julia> @macroexpand1 @macro1 x
:((Main.x, x))

julia> @macroexpand1 @macro2 x
:(#= REPL[2]:3 =# @foo (x, $(Expr(:escape, :x))))

```

I was expecting `:(Main.@foo (Main.x, x))` as the result of `@macro2`. Is this the expected behavior?

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 6, 2020, 9:33pm UTC](https://discourse.julialang.org/t/escaping-expressions-within-macro-calls/46160/2 "2020-09-06T21:33:53Z")

</div>

Indeed it is! Macros apply to the entire expression to the right of them. If you want them not to, you need to use parentheses. This can indeed seem like a “gotcha”, but see the following example:

```julia
julia> a = rand(10);

julia> +(@view a[1:2], [3, 4])
ERROR: LoadError: ArgumentError: Invalid use of @view macro: argument must be a reference expression A[...].
Stacktrace:
 [1] @view(::LineNumberNode, ::Module, ::Any) at ./views.jl:114
in expression starting at REPL[1857]:1

julia> +(@view(a[1:2]), [3, 4])
2-element Array{Float64,1}:
 3.332961332207635
 4.815458815609289

```

Many macros must be able to work even across equal signs, commas, etc., so this behavior is necessary.

---

<div class="post-metadata">

**Author:** ![lucas711642](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lucas711642/32/12051_2.png) [@lucas711642](https://discourse.julialang.org/u/lucas711642)\
**Post date:** [September 6, 2020, 10:17pm UTC](https://discourse.julialang.org/t/escaping-expressions-within-macro-calls/46160/3 "2020-09-06T22:17:50Z")

</div>

I’m sorry, I think I wasn’t clear enough. My question was not about the number of arguments in the `@foo` call. I’m asking if `@macro2` shouldn’t process any `esc()` calls within `@foo`.

A simpler example:

```julia
julia> macro macro3(expr)
       :(@foo $(esc(expr)))
       end;

julia> @macroexpand1 @macro3 x
:(#= REPL[1]:2 =# @foo $(Expr(:escape, :x)))

```

Shouldn’t the result be `Main.@foo x`?

I guess I could achieve what I want in `@macro2` with:

```julia
macro macro4(expr)
	:($(@ __MODULE__ ).@foo $(@ __MODULE__ ).$expr, $expr)
end

```

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [September 6, 2020, 10:30pm UTC](https://discourse.julialang.org/t/escaping-expressions-within-macro-calls/46160/4 "2020-09-06T22:30:16Z")

</div>

Macros are actually special here, because quoted macrocalls in other macros get expanded inside that macro’s definition, not inside its caller. So in this case `@foo` is already expanded inside `@macro3`, that’s why there’s no need for lowering to make it a `GlobalRef`. This should illustrate what is going on:

```julia
julia> macro m()
           @show __source__
           @show (@ __LINE__ , @ __FILE__ )
           :(@ __LINE__ , @ __FILE__ )
       end
@m (macro with 1 method)

julia> @m
__source__ = :(#= REPL[2]:1 =#)
(#= REPL[1]:3 =# @ __LINE__ (), #= REPL[1]:3 =# @ __FILE__ ()) = (3, "REPL[1]")
(4, "REPL[1]")

```

Does that help?

---

<div class="post-metadata">

**Author:** ![lucas711642](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lucas711642/32/12051_2.png) [@lucas711642](https://discourse.julialang.org/u/lucas711642)\
**Post date:** [September 7, 2020, 12:12am UTC](https://discourse.julialang.org/t/escaping-expressions-within-macro-calls/46160/5 "2020-09-07T00:12:45Z")

</div>

That indeed helped. Thanks.
