# How to understand expression interpolation

**URL:** <https://discourse.julialang.org/t/how-to-understand-expression-interpolation/7351>\
**Category:** General Usage\
**Tags:** question\
**Created:** [November 28, 2017, 8:10am UTC](https://discourse.julialang.org/t/how-to-understand-expression-interpolation/7351 "2017-11-28T08:10:09Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Chong\_Wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chong_wang/32/20307_2.png) [@Chong\_Wang](https://discourse.julialang.org/u/Chong_Wang)\
**Post date:** [November 28, 2017, 8:10am UTC](https://discourse.julialang.org/t/how-to-understand-expression-interpolation/7351/1 "2017-11-28T08:10:09Z")

</div>

Look at the following two code snippets.

1. 

```julia
module Foo

export @bar

struct foo
end

macro bar(ex)
    temp = foo
    eval(current_module(), :($temp))
    return esc(ex)
end

end

using Foo

@bar :(Here)

```

1. 

```julia
module Foo

export @bar

struct foo
end

macro bar(ex)
    eval(current_module(), :(foo))
    return esc(ex)
end

end

using Foo

@bar :(Here)

```

In my understanding, the two snippets are effectively the same, since interpolation is basically substitution. However, the first snippet works as expected while the second complains “LoadError: UndefVarError: foo not defined”.

What is happening here?

---

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [November 28, 2017, 9:25am UTC](https://discourse.julialang.org/t/how-to-understand-expression-interpolation/7351/2 "2017-11-28T09:25:52Z")

</div>

1. 

```julia
macro bar(ex)
    temp = foo # expands to Foo.foo
    eval(current_module(), :($temp))
    return esc(ex)
end

```

1. 

```julia
macro bar(ex)    
    eval(current_module(), :(foo)) # still just `foo` which is undefined in Main
    return esc(ex)
end

```

I believe it’s part of [macro hygiene](https://docs.julialang.org/en/latest/manual/metaprogramming.html#Hygiene-1).

Also I understand that it’s just a toy example, but I’m still suspicious about using `eval()` inside of a macro.

---

<div class="post-metadata">

**Author:** ![Chong\_Wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chong_wang/32/20307_2.png) [@Chong\_Wang](https://discourse.julialang.org/u/Chong_Wang)\
**Post date:** [November 28, 2017, 10:27am UTC](https://discourse.julialang.org/t/how-to-understand-expression-interpolation/7351/3 "2017-11-28T10:27:50Z")

</div>

I am stilled confused. In my understanding, macro hygiene deals with expressions returned by macro, not the body of macro. Do I misunderstand something?

---

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [November 28, 2017, 12:04pm UTC](https://discourse.julialang.org/t/how-to-understand-expression-interpolation/7351/4 "2017-11-28T12:04:02Z")

</div>

It might not be logically a part of hygiene features, but it’s a related one. The point is that macros in Julia are a bit more complicated than just substituting some text. In your first example:

```julia
macro bar(ex)
    temp = foo
    eval(current_module(), :($temp))
    return esc(ex)
end

```

Julia knows that the macro is defined in module `Foo`, so `foo` refers to `Foo.foo`. Thus when you use this macro in another module, during macroexpand time Julia assigns `temp = Foo.foo` and then evaluates `:($temp)` in the context of that module:

```julia
macro bar(ex)
    temp = foo
    x = eval(current_module(), :($temp))
    println(x)
    return esc(ex)
end
...
macroexpand(:(@bar :(Here)))
# prints "Foo.foo"

```

Note how Julia conveniently found the correct object `foo` from the scope of macro definition. It’s very similar to example with `time` from hygiene section of manual I pointed to, even though `time` is used in a returned expression while `foo` is only used in body of the macro.

In your second example you don’t actually have any references to `Foo.foo`, but just a symbol `:foo`. For Julia symbol `:foo` is just data, so it’s passed as is. During macroexpand time when you call `eval(current_module(), :(foo))` Julia tries to find a thing called `foo` in the current module (`Main`), but it’s not defined:

```julia
macro bar(ex)    
    x = eval(current_module(), :(foo))
    println(x)
    return esc(ex)
end
...
@bar :(Here)
# ERROR: UndefVarError: foo not defined

```

Though, if you define `foo` in `Main`, it will work fine:

```julia
foo = "macroprogramming is awesome!"
@bar :(Here)
# prints "macroprogramming is awesome!"

```

---

<div class="post-metadata">

**Author:** ![Chong\_Wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chong_wang/32/20307_2.png) [@Chong\_Wang](https://discourse.julialang.org/u/Chong_Wang)\
**Post date:** [November 28, 2017, 1:05pm UTC](https://discourse.julialang.org/t/how-to-understand-expression-interpolation/7351/5 "2017-11-28T13:05:43Z")

</div>

Thank you.

Is this one of the small tricks that julia does or is there a complete theory of interpolation? If the latter is true, any good references?

---

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [November 28, 2017, 2:21pm UTC](https://discourse.julialang.org/t/how-to-understand-expression-interpolation/7351/6 "2017-11-28T14:21:05Z")

</div>

This implementation is bound to Julia module and compilation systems and thus is different from other implementations, but in general the question of how (not) to mix things from macro definition and macro expansion scope, as well as macro definition, macro expansion time and run time are well-known. For example, in Common Lisp there’s no macro hygiene - you get (almost) what you have written in a returned expression. But it brings a problem of [capturing enclosing variables](https://en.wikipedia.org/wiki/Hygienic_macro#The_hygiene_problem), so Common Lispers have to use `(gensym)` - a function generating unique names - to protect expanded code. Yet in practice it’s quite error-prone, so many languages, including Julia, moved to hygienic approach, generating unique names by default:

```julia
macro baz(x)
    return quote
        y = 2x
        z = y + 1
        print(z)
    end
end

macroexpand(:(@baz 42))

```

which produces (note intermediate variable names):

```julia
quote # none, line 3:
    #3#y = 2 * Main.x # none, line 4:
    #4#z = #3#y + 1 # none, line 5:
    (Main.print)(#4#z)
end

```

Now consider yet another example:

```julia
module Foo

macro my_macro()
    print(foo)
end

function my_func()
    print(foo)
end

end

# Main
import Foo

struct foo
end

Foo.my_func()
Foo.@my_macro()

```

As mentioned by someone else here, macros in Julia are just functions with funny names. And as functions, they obey normal rules of name resolution: although macro `my_macro` is expanded in `Main`, it’s _defined_ in `Foo`, just like function `my_func`.

As expected, In both cases Julia tries to resolve the name `foo` in the context of `Foo` and, as expected, it fails for both - function and macro calls.

---

<div class="post-metadata">

**Author:** ![Chong\_Wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chong_wang/32/20307_2.png) [@Chong\_Wang](https://discourse.julialang.org/u/Chong_Wang)\
**Post date:** [November 28, 2017, 3:18pm UTC](https://discourse.julialang.org/t/how-to-understand-expression-interpolation/7351/7 "2017-11-28T15:18:59Z")

</div>

Thank you.
