# How to construct \`Expr(:tuple, ...)\` using templates

**URL:** <https://discourse.julialang.org/t/how-to-construct-expr-tuple-using-templates/1305>\
**Category:** General Usage\
**Tags:** question\
**Created:** [January 5, 2017, 3:56pm UTC](https://discourse.julialang.org/t/how-to-construct-expr-tuple-using-templates/1305 "2017-01-05T15:56:38Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 5, 2017, 3:56pm UTC](https://discourse.julialang.org/t/how-to-construct-expr-tuple-using-templates/1305/1 "2017-01-05T15:56:38Z")

</div>

I tried to make an argument list for a closure from a tuple of symbols. MWE:

```julia
## what I want
macro_helper1(arguments, form) = :($(Expr(:tuple, arguments...)) -> $form)
## how I tried to do it first
macro_helper2(arguments, form) = :($arguments -> $form)

```

difference:

```julia
julia> macro_helper1((gensym(:a),gensym(:b)), :(f(something))) # good solution
:((##a#321,##b#322)->begin # REPL[168], line 1:
            f(something)
        end)

julia> macro_helper2((gensym(:a),gensym(:b)), :(f(something))) # wrong solution
:((Symbol("##a#323"),Symbol("##b#324"))->begin # REPL[170], line 1:
            f(something)
        end)

```

I figured out the `Expr(:tuple,...)` using `dump`.

1. Is this the expected behavior?
2. Could someone please explain why? (I would learn a lot from it).
3. How to do this without `Expr`?

---

<div class="post-metadata">

**Author:** ![MikeInnes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikeinnes/32/3656_2.png) [@MikeInnes](https://discourse.julialang.org/u/MikeInnes)\
**Post date:** [January 5, 2017, 4:39pm UTC](https://discourse.julialang.org/t/how-to-construct-expr-tuple-using-templates/1305/2 "2017-01-05T16:39:54Z")

</div>

When evaluating an expression tree, the only thing that has any meaning is an `Expr` object (to a first approximation at least). Everything else is treated as a black box by the compiler and simply left alone. For example:

```julia
type Foo
  x
end

eval(Expr(:call, :+, :a, Foo(:(b+c))))
# which is equivalent to
a + Foo(:(b+c))
# NOT to
a + Foo(b + c)

```

If you evaluate this expression, `b+c` will never be evaluated, because a `Foo` has to be left as-is. In your case you’re working with a `Tuple` rather than a `Foo` but the principle is exactly the same.

So in your example, what’s happening is that the compiler looks for a set of names to serve as the argument list, but it only finds a value it isn’t allowed to look at – since it can only look inside an `Expr(:tuple)`.

In theory there could be rules for how tuples (or arbitrary objects) are interpreted as expressions so that there’s effectively no difference between `:(a, b)` and `(:a, :b)`. This would make your example behave more intuitively, but would also make the boundary between code and data in `Expr` objects much more complex.

Tuple expressions can be constructed in the normal way by quoting them: `:(a, b)`, `:(foo((1,2)))` etc. And you can splice into them as usual as well; the trick is to start with a one-element tuple expression `:(a,)` and unquote-splat `:($(xs...),)`, making the final version:

```julia
macro_helper1(arguments, form) = :(($(arguments...),) -> $form)

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 5, 2017, 6:32pm UTC](https://discourse.julialang.org/t/how-to-construct-expr-tuple-using-templates/1305/3 "2017-01-05T18:32:07Z")

</div>

Thanks, now I get how everything but `Expr` is untouched. It not the level of homoiconicity Lisp has, but it is consistent once one knows the rule.

I think I also understand the tuple construction, mostly. If I dropped the `,` and had

```julia
:(($(arguments...)) -> $form)

```

then it would be equivalent to

```julia
:($(arguments...) -> $form)

```

which makes

```julia
Expr
  head: Symbol ->
  args: Array{Any}((3,))
    1: Symbol a
    2: Symbol b
    3: Expr
      head: Symbol block
      args: Array{Any}((2,))
        1: Expr
          head: Symbol line
          args: Array{Any}((2,))
            1: Int64 1
            2: Symbol REPL[190]
          typ: Any
        2: Symbol form
      typ: Any
  typ: Any

```

which somehow splices as a `->` with **3 args** , which is invalid. It is curious that one can do this (but apparently validation does not happen before evaluation). So I need to tell Julia that I want a tuple, hence the `,`. Is this correct?

---

<div class="post-metadata">

**Author:** ![MikeInnes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikeinnes/32/3656_2.png) [@MikeInnes](https://discourse.julialang.org/u/MikeInnes)\
**Post date:** [January 5, 2017, 7:14pm UTC](https://discourse.julialang.org/t/how-to-construct-expr-tuple-using-templates/1305/4 "2017-01-05T19:14:30Z")

</div>

Yup, that’s it.

```julia
:($a -> $b) == Expr(:->, a, b)
:($(a...) -> $b) == Expr(:->, a..., b)
:($x,) == Expr(:tuple, x)
:($(x...),) == Expr(:tuple, x...)

```

Unfortunately the abstraction isn’t 100% waterproof. There may be an argument for special casing how splats at certain locations are handled, but I’m not sure whether it’d be worth the loss of consistency. OTOH it lets you do some fun things like:

```julia
x = [:f, 1, 2]
:($(x...)()) == :(f(1,2))

```

(which will make sense if you expand it like the above).
