# Expression interpolation

in doc, the following example is given:

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

I don’t get the meaning of “expression interpolation”, as:

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

julia> ex == ex2
true
``````

why we need to do it in the way of `ex`, but not simply `ex2`? thanks.

I think the point is…everything inside `:()` is verbatim except for things wrapped inside \$, which are evaluated beforehand. So, the following is “wrong”

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

but this is “right”:

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

I think it is the very point the relevant section of the doc is making.

2 Likes

interpolating a variable, as in your `\$t` example, is well understood. But I have difficulty in understanding the interpolation of an expression.

e.g.

``````julia> :(a - (1 + 1) )
:(a - (1 + 1))

julia> :(a - \$:( (1 + 1) )  )
:(a - (1 + 1))
``````

seems like:

1. `:( )` would quote something, i.e. prevent the thing inside being evaluated.
2. `\$` would evaluate the thing after it.

so, the question is: what’s the use of `\$:( )`??? it seems to me that the quoting and interpolation just cancels each other and do nothing??? In that example of the docs, there is no advantage to using interpolation. A better and more useful example should probably be provided. It is indeed a useless example, since it is not a useful usecase. However, the point of interpolation is that you want to evaluate or construct a piece of code before inserting it into the expression. Therefore, a better example could be made in the docs, where the usefulness is emphasized.

… so, could we have “a better example” here? thanks. The example could be written as

``````julia> ex1 = :((1, 2, 3))
:((1, 2, 3))

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

Since you are interpolating into an expression with `\$`, you need another expression, which is constructed using `:`.

`Expr(:tuple, 1, 2, 3)` gives the same expression as `:(1, 2, 3)`, so one could have used

``````ex = :(a in \$(Expr(:tuple, 1, 2, 3)))
``````

It’s just slightly more cumbersome.

FWIW, I think that example is fine. It’s just that working with AST requires some exploration, so that chapter should be read from the begining, with the user experimenting with `dump` and all the examples there to understand expressions.

2 Likes

(also, moved to Usage, working with ASTs is beyond First steps)

I think it is probably important to note that interpolating a variables and expression in an expression lead to slightly different things.

``````julia> v = (1,2,3)
julia> dump(:(a in \$v))
Expr
args: Array{Any}((3,))
1: Symbol in
2: Symbol a
3: Tuple{Int64,Int64,Int64}
1: Int64 1
2: Int64 2
3: Int64 3
``````
``````julia> dump(:(a in (1,2,3)))

Expr
args: Array{Any}((3,))
1: Symbol in
2: Symbol a
3: Expr
args: Array{Any}((3,))
1: Int64 1
2: Int64 2
3: Int64 3
``````

and if you don’t interpolate the expression you get.

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

So really what it looks like interpolating the expression does is to unwrap the inner expression and pass it as an argument. I.E. The respective difference is:

``````julia> Expr(:call, :in, :a, (1,2,3))
:(a in (1, 2, 3))

julia> Expr(:call, :in, :a, :((1,2,3)))
:(a in (1, 2, 3))

julia> Expr(:call, :in, :a, Expr(:quote, :(1,2,3)))
:(a in \$(Expr(:quote, :((1, 2, 3)))))
``````