# Question on Metaprogramming Example from Docs

**URL:** <https://discourse.julialang.org/t/question-on-metaprogramming-example-from-docs/75992>\
**Category:** General Usage\
**Tags:** metaprogramming\
**Created:** [February 8, 2022, 4:07am UTC](https://discourse.julialang.org/t/question-on-metaprogramming-example-from-docs/75992 "2022-02-08T04:07:20Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![TI36XPro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ti36xpro/32/33658_2.png) [@TI36XPro](https://discourse.julialang.org/u/TI36XPro)\
**Post date:** [February 8, 2022, 4:07am UTC](https://discourse.julialang.org/t/question-on-metaprogramming-example-from-docs/75992/1 "2022-02-08T04:07:21Z")

</div>

Hello,

I have been reviewing the metaprogamming section of the docs and I have come across something I don’t understand. I am looking at the second example in the subsection on interpolation, [here](https://docs.julialang.org/en/v1/manual/metaprogramming/#man-expression-interpolation). The example is showing how you can interpolate a tuple into an expression.

```julia
julia> ex = :(a in $:((1,2,3)) )
:(a in (1, 2, 3))

```

My question is - why is the tuple quoted a second time?

I just tried

```julia
ex = :(a in $(1, 2, 3))

```

and it appears to work the same. Am I missing something?

---

<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:** [February 8, 2022, 8:53am UTC](https://discourse.julialang.org/t/question-on-metaprogramming-example-from-docs/75992/2 "2022-02-08T08:53:30Z")

</div>

[`dump`](https://docs.julialang.org/en/v1/base/io-network/#Base.dump) is often a good way to examine expressions in details. Here, it shows that the two expressions you build in your example are subtly different:

```julia
julia> :(a in $:((1,2,3)) ) |> dump
Expr
  head: Symbol call
  args: Array{Any}((3,))
    1: Symbol in
    2: Symbol a
    3: Expr
      head: Symbol tuple
      args: Array{Any}((3,))
        1: Int64 1
        2: Int64 2
        3: Int64 3

julia> :(a in $(1,2,3) ) |> dump
Expr
  head: Symbol call
  args: Array{Any}((3,))
    1: Symbol in
    2: Symbol a
    3: Tuple{Int64, Int64, Int64}
      1: Int64 1
      2: Int64 2
      3: Int64 3

```

One thing to notice is that the way shown in the documentation produces exactly the same expression as a plain `a in (1,2,3)`, which is perhaps why it would be preferred:

```julia
julia> :(a in (1,2,3) ) |> dump
Expr
  head: Symbol call
  args: Array{Any}((3,))
    1: Symbol in
    2: Symbol a
    3: Expr
      head: Symbol tuple
      args: Array{Any}((3,))
        1: Int64 1
        2: Int64 2
        3: Int64 3

```

That being said, I believe in this case all expressions work in the same way in practice, because the tuple `(1,2,3)` is a literal that evaluates to itself (i.e. evaluating it once more does not change its value):

```julia
julia> a = 2
2

julia> eval(:(a in (1,2,3) ))
true

julia> eval(:(a in $:((1,2,3)) ))
true

julia> eval(:(a in $(1,2,3)) )
true

```

---

<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:** [February 9, 2022, 1:15am UTC](https://discourse.julialang.org/t/question-on-metaprogramming-example-from-docs/75992/3 "2022-02-09T01:15:18Z")

</div>

Just to add to the above: that section of the docs is intentionally demonstrating that you can interpolate an Expr into another Expr. This is different from simply interpolating some object in that place. Consider an expression which does _not_ evaluate to itself (the Tuple does, as @ffevotte demonstrated above), i.e. not a “literal”.

```julia
julia> :(a in $:(1+1))
:(a in 1 + 1)

julia> :(a in 1+1)
:(a in 1 + 1)

julia> :(a in $(1+1))
:(a in 2)

```

In the first case, the expression is interpolated as-is. The second case is _exactly_ the same as first. Interpolating the `1+1` in the first expression produces the second expression, the same as if I had written it out by hand. In the last case, the value of `1+1` is computed, then the interpolation takes place.  
Why does this distinction matter? Consider:

```julia
julia> :(a in $:((x + 1)))
:(a in x + 1)

julia> :(a in $(x + 1))
ERROR: UndefVarError: x not defined

```

Notice that `x` doesn’t exist, so the second case throws an error. It’s impossible to compute `x+1` at the moment. However, I can create an expression that _when evaluated_ computes `x+1` as part of it (that’s what the first case does). By the time it’s evaluated, I can ensure that some variable called `x` exists in scope so the whole thing works. This kind of composing of larger expressions out of smaller expressions is extremely important, particularly when writing macros. You might see building up of expressions like the following:

```julia
julia> var = :x;

julia> e = :($var + 1);

julia> f = :(sin ∘ Float16);

julia> small_ex = :($f.(1:$e))
:((sin ∘ Float16).(1:x + 1))

julia> larger_ex = :(map($var -> $small_ex, 1:5))
:(map((x->begin
              (sin ∘ Float16).(1:x + 1)
          end), 1:5))

julia> eval(ans)
5-element Vector{Vector{Float16}}:
 [0.8413, 0.909]
 [0.8413, 0.909, 0.1411]
 [0.8413, 0.909, 0.1411, -0.757]
 [0.8413, 0.909, 0.1411, -0.757, -0.959]
 [0.8413, 0.909, 0.1411, -0.757, -0.959, -0.2793]

```

In each step above, I’m interpolating an expression into place, not the value of that expression. The `eval` is just to demonstrate that that expression is valid, and what it does. In practice, macros end up “eval-ing” themselves after the expression is created.

---

<div class="post-metadata">

**Author:** ![TI36XPro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ti36xpro/32/33658_2.png) [@TI36XPro](https://discourse.julialang.org/u/TI36XPro)\
**Post date:** [February 9, 2022, 1:24am UTC](https://discourse.julialang.org/t/question-on-metaprogramming-example-from-docs/75992/4 "2022-02-09T01:24:10Z")

</div>

Thank you - both answers are very helpful and I understand this a little better now.
