# macros at parse and runtime

**URL:** https://discourse.julialang.org/t/macros-at-parse-and-runtime/12738
**Category:** New to Julia
**Tags:** metaprogramming
**Created:** [July 30, 2018, 12:59pm UTC](https://discourse.julialang.org/t/macros-at-parse-and-runtime/12738 "2018-07-30T12:59:11Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![AmjadHD](https://avatars.discourse-cdn.com/v4/letter/a/3d9bf3/32.png) [@AmjadHD](https://discourse.julialang.org/u/AmjadHD)
#### Post date: [July 30, 2018, 12:59pm UTC](https://discourse.julialang.org/t/macros-at-parse-and-runtime/12738/1 "2018-07-30T12:59:11Z")

</div>

I was recently the macro functionality, and specifically what happens at parse and at runtime:

```julia
macro parse_run(arg)
    println("at Parse time, The argument is: ", arg)
    return :(println("at Runtime, The argument is: ", $arg))
end

function test_macro(name::String)
    @parse_run name
end

test_macro("Amjad")

```

I was expecting `test_macro` to print : “at Runtime, The argument is: Amjad” but instead got this error:

```julia
at Parse time, The argument is: name
ERROR: LoadError: UndefVarError: name not defined
Stacktrace:
 [1] test_macro(::String) at C:\Users\User\Desktop\Tfach\LSP tests\test.jl:7
 [2] include_from_node1(::String) at .\loading.jl:576
 [3] include(::String) at .\sysimg.jl:14
 [4] process_options(::Base.JLOptions) at .\client.jl:305
 [5] _start() at .\client.jl:371
while loading C:\Users\User\Desktop\Tfach\LSP tests\test.jl, in expression starting on line 10

```

why doe’s this happen ? and why doesn’t this happen with the `@assert name == "John"` ? thanks in advance, and thanks for the revolution you made 👏

---

<div class="post-metadata">

### Author: ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)
#### Post date: [July 30, 2018, 1:06pm UTC](https://discourse.julialang.org/t/macros-at-parse-and-runtime/12738/2 "2018-07-30T13:06:58Z")

</div>

```julia
return :(println("at Runtime, The argument is: ", $arg))

```

arg == `:name`, if you splice that into your expression, it will get turned into something like `##1name`, to make it hygienic (so you dont refer to local variables by accidant). If you want to make it refer to an actually variable in the calling scope of the macro use `esc`:

```nohighlight
macro parse_run(arg)
    println("at Parse time, The argument is: ", arg)
    return :(println("at Runtime, The argument is: ", $(esc(arg))))
end
julia> function test_macro(name::String)
           @parse_run name
       end
at Parse time, The argument is: name

julia> test_macro("Amjad")
at Runtime, The argument is: Amjad

```

---

<div class="post-metadata">

### Author: ![AmjadHD](https://avatars.discourse-cdn.com/v4/letter/a/3d9bf3/32.png) [@AmjadHD](https://discourse.julialang.org/u/AmjadHD)
#### Post date: [July 30, 2018, 1:34pm UTC](https://discourse.julialang.org/t/macros-at-parse-and-runtime/12738/3 "2018-07-30T13:34:24Z")

</div>

Thanks for the help, I was so close from this but I tried `esc($arg))` instead of `$(esc(arg))`. so esc actually returns a string here ?

---

<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: [July 30, 2018, 4:05pm UTC](https://discourse.julialang.org/t/macros-at-parse-and-runtime/12738/4 "2018-07-30T16:05:06Z")

</div>

> [@sdanisch](#):
>
> it will get turned into something like `##1name`

In this case it’ll be a global reference instead.

> [@AmjadHD](#):
>
> so esc actually returns a string here ?

No. The runtime value cannot be known at compile time (which sounds silly but is very important) so the return value of `esc` is still returns a variable reference (a expression) and not it’s runtime value (the string value).

`esc` returns something, the exact form is an implementation detail that’s no important here, so that the macro expansion code will make sure it reference the variable `name` in the caller (macro user) scope instead of the callee (macro writer) scope.

You can see what it returns by just printing it although it’ll only tell you what the implementation defined special expresion that has the property above. You can see the effect of it in the macro expander by checking `@macroexpand @parse_run name` for the two implementation.
