# Eval() vs @eval

#1

I expected that the two forms would yield identical results. But to my surprise:

``````julia> @eval :x
:x

julia> eval(:x)
ERROR: UndefVarError: x not defined
Stacktrace:
[1] top-level scope
[2] eval at ./boot.jl:319 [inlined]
[3] eval(::Symbol) at ./client.jl:389
[4] top-level scope at none:0
``````

Is that to be expected?

#2

OK, they definitely don’t have the same behaviour:

``````julia> ex = :(x = 2)
:(x = 2)

julia> eval(ex)
2

julia> x
2

julia> ex = :(y = 2)
:(y = 2)

julia> @eval ex
:(y = 2)

julia> y
ERROR: UndefVarError: y not defined
``````

#3

#4

Nevermind, I figured it out… Silly me, the `@eval` macro should take an expression as an argument, not a Symbol!

#5

Yes. The input to macros is always converted to an expression, the output is getting evaluated. So, when you do `@eval :x`, inside the macro the argument is `:(:x)`. When that gets returned, it is evaluated, giving the symbol `:x`.

By contrast, `eval` takes as an argument an `Expr` or `Symbol` object. So, when it runs, it’s running the code contained in that `Expr` (or `Symbol`) which is in this case just `x`.

#6

Thanks – I figured it out that I was `@eval`ing a Symbol into existence.

#7

Yessss, thank you!

#8

You can splice expressions into `@eval`, so you can make your examples work:

``````julia> ex = :(y = 2)
:(y = 2)

julia> @eval \$ex
2

julia> y
2
``````