# Use of \`eval(QuoteNode(expr))\`

**URL:** <https://discourse.julialang.org/t/use-of-eval-quotenode-expr/22328>\
**Category:** New to Julia\
**Tags:** macros, metaprogramming\
**Created:** [March 26, 2019, 1:23am UTC](https://discourse.julialang.org/t/use-of-eval-quotenode-expr/22328 "2019-03-26T01:23:43Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kiuhnm\_Mnhuik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kiuhnm_mnhuik/32/7572_2.png) [@Kiuhnm\_Mnhuik](https://discourse.julialang.org/u/Kiuhnm_Mnhuik)\
**Post date:** [March 26, 2019, 1:23am UTC](https://discourse.julialang.org/t/use-of-eval-quotenode-expr/22328/1 "2019-03-26T01:23:44Z")

</div>

The official documentation [says](https://docs.julialang.org/en/v1/manual/metaprogramming/#Hygiene-1) that `@eval expr` returns `eval(QuoteNode(expr))`. Why not simply `expr`?  
Does it have something to do with interpolation?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 26, 2019, 1:36am UTC](https://discourse.julialang.org/t/use-of-eval-quotenode-expr/22328/2 "2019-03-26T01:36:11Z")

</div>

That’s wrong. It’s returning an expression that `eval`s the quoted version of `expr`, i.e. the expression it returns unquoted is more or less `eval($(QuoteNode(expr)))`.

---

<div class="post-metadata">

**Author:** ![Kiuhnm\_Mnhuik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kiuhnm_mnhuik/32/7572_2.png) [@Kiuhnm\_Mnhuik](https://discourse.julialang.org/u/Kiuhnm_Mnhuik)\
**Post date:** [March 26, 2019, 1:10pm UTC](https://discourse.julialang.org/t/use-of-eval-quotenode-expr/22328/3 "2019-03-26T13:10:26Z")

</div>

Sorry, but I still can’t see the difference between the following two macros:

```julia
macro m1(expr)
    eval(QuoteNode(expr))
end

```

and

```julia
macro m2(expr)
    expr
end

```

Isn’t the `eval` above being executed at parse time? And Isn’t `eval(QuoteNode(x))` just `x`, in general?  
Could you please provide a minimal example where `m1` and `m2` show different behavior?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 26, 2019, 1:28pm UTC](https://discourse.julialang.org/t/use-of-eval-quotenode-expr/22328/4 "2019-03-26T13:28:44Z")

</div>

What I mean is that the document is wrong. It also does not mean what you write though. The expression in the doc was meant to be the returned expression of the macro, not the implementation of the macro so not, `eval` is not executed at parse time. What I said is that the implementation is more or less `return :(eval($(QuoteNode(expr))))`

---

<div class="post-metadata">

**Author:** ![Kiuhnm\_Mnhuik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kiuhnm_mnhuik/32/7572_2.png) [@Kiuhnm\_Mnhuik](https://discourse.julialang.org/u/Kiuhnm_Mnhuik)\
**Post date:** [March 26, 2019, 6:17pm UTC](https://discourse.julialang.org/t/use-of-eval-quotenode-expr/22328/5 "2019-03-26T18:17:17Z")

</div>

Thanks, that helped. _Is there a way to see the rewriting steps and not just the final result?_  
Your example doesn’t work, but you did write “more or less”. This seems to work:

```julia
julia> macro my_eval(expr)
           :(eval($(Expr(:quote, expr))))
       end
@my_eval (macro with 1 method)

julia> a = 1; @my_eval $a
1

```

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [March 26, 2019, 6:28pm UTC](https://discourse.julialang.org/t/use-of-eval-quotenode-expr/22328/6 "2019-03-26T18:28:03Z")

</div>

> [@Kiuhnm\_Mnhuik](#):
>
> Is there a way to see the rewriting steps and not just the final result?

Are you looking for `@macroexpand`?

```julia
@macroexpand @my_eval $a

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 26, 2019, 6:39pm UTC](https://discourse.julialang.org/t/use-of-eval-quotenode-expr/22328/7 "2019-03-26T18:39:30Z")

</div>

Yes that is the “more or less” part. `QuoteNode` and `Expr(:quote)` treats `$` differently. This should be mentioned already in the (dev) doc for expression types/heads but I didn’t check to make sure.

Depending on what you mean as the rewriting step and final result, `@macroexpand` gives you the result of the macro which include macro hygiene rewrite but not lowering. If you want to see the bare result of the macro without anything else, you can manually call the macro, which is nothing more than a badly named function…

```julia
julia> (@eval Base.$(Symbol("@eval")))(LineNumberNode(1), Main, :aaaa)
:(Core.eval(Main, :aaaa))

```

Do note that you’ll need to be more careful if you want to pass a expression with `$` in. The easiest way I can think of now is to actually write a macro that returns the correctly quoted expression for you, i.e.

```julia
julia> macro m(expr)
           QuoteNode(expr)
       end
@m (macro with 1 method)

julia> @m $a
:($(Expr(:$, :a)))

julia> (@eval Base.$(Symbol("@eval")))(LineNumberNode(1), Main, (@m $a))
:(Core.eval(Main, $(Expr(:quote, :($(Expr(:$, :a)))))))

julia> (@eval Base.$(Symbol("@eval")))(LineNumberNode(1), Main, $a)
ERROR: syntax: "$" expression outside quote

```

(Note the use of `QuoteNode` in this case)

Note that you can also just look at the definition directly. [https://github.com/JuliaLang/julia/blob/8649af9abed7d628567f68bf280113ce05d76d3f/base/essentials.jl#L178](https://github.com/JuliaLang/julia/blob/8649af9abed7d628567f68bf280113ce05d76d3f/base/essentials.jl#L178) I find all the methods for `@eval` by calling `methods` on the function `@eval` and if you know the signature you want to call it with you can also use `@which`.

```julia
julia> @which @eval a
@eval( __source__ ::LineNumberNode, __module__ ::Module, ex) in Base at essentials.jl:166

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 26, 2019, 6:47pm UTC](https://discourse.julialang.org/t/use-of-eval-quotenode-expr/22328/8 "2019-03-26T18:47:51Z")

</div>

Or

```julia
julia> macro call_macro(expr)
           @assert expr.head == :macrocall
           return :($(esc(expr.args[1]))($(QuoteNode(expr.args[2])), $ __module__ , $(QuoteNode.(expr.args[3:end])...)))
       end
@call_macro (macro with 1 method)

julia> @call_macro @eval a
:(Core.eval(Main, :a))

julia> @call_macro @eval $a
:(Core.eval(Main, $(Expr(:quote, :($(Expr(:$, :a)))))))

julia> eval(@call_macro @eval $a)
ERROR: UndefVarError: a not defined
Stacktrace:
 [1] top-level scope at none:0
 [2] eval at ./boot.jl:328 [inlined]
 [3] eval(::Expr) at ./client.jl:404
 [4] top-level scope at none:0

julia> a = 2
2

julia> eval(@call_macro @eval $a)
2

```

---

<div class="post-metadata">

**Author:** ![Kiuhnm\_Mnhuik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kiuhnm_mnhuik/32/7572_2.png) [@Kiuhnm\_Mnhuik](https://discourse.julialang.org/u/Kiuhnm_Mnhuik)\
**Post date:** [March 27, 2019, 4:44pm UTC](https://discourse.julialang.org/t/use-of-eval-quotenode-expr/22328/9 "2019-03-27T16:44:48Z")

</div>

Thanks for the detailed answers. Maybe I’m doing something wrong but `methods` doesn’t work with macros so I had to write something like this:

```julia
macro methods(expr)
    is_macro = isa(expr, Expr) && expr.head == :macrocall
    :(methods($(esc(is_macro ? expr.args[1] : expr))))
end

```

I’ll start reading the developer’s documentation right now. Sorry if I asked about things that were already explained there.
