# How to use destructuring assignment with macro?

**URL:** <https://discourse.julialang.org/t/how-to-use-destructuring-assignment-with-macro/7385>\
**Category:** General Usage\
**Tags:** question, macros\
**Created:** [November 29, 2017, 1:02pm UTC](https://discourse.julialang.org/t/how-to-use-destructuring-assignment-with-macro/7385 "2017-11-29T13:02:42Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![ta2gch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ta2gch/32/10663_2.png) [@ta2gch](https://discourse.julialang.org/u/ta2gch)\
**Post date:** [November 29, 2017, 1:02pm UTC](https://discourse.julialang.org/t/how-to-use-destructuring-assignment-with-macro/7385/1 "2017-11-29T13:02:42Z")

</div>

I expect this macro to define variables with **same** characters, but it doesn’t work.  
How should I write this?

```julia
macro chars(cs...)
    return :( $(esc(cs)) = $(map(c->string(c)[1], cs)) )
end

@chars a b c # is '(a,b,c) = ('a','b','c')

```

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [November 29, 2017, 1:37pm UTC](https://discourse.julialang.org/t/how-to-use-destructuring-assignment-with-macro/7385/2 "2017-11-29T13:37:50Z")

</div>

```julia
macro chars(cs...)
    return :( $(esc(Expr(:tuple, cs...))) = $(map(c->string(c)[1], cs)) )
end

@chars a b c

```

I did

```julia
dump(quote 
        a,b,c = 1,2,3
        end)

```

to figure it out.

---

<div class="post-metadata">

**Author:** ![ta2gch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ta2gch/32/10663_2.png) [@ta2gch](https://discourse.julialang.org/u/ta2gch)\
**Post date:** [November 29, 2017, 2:37pm UTC](https://discourse.julialang.org/t/how-to-use-destructuring-assignment-with-macro/7385/3 "2017-11-29T14:37:16Z")

</div>

Thank you. I have a question. What difference is it between `cs` and `Expr(:tuple, cs...)`? `cs` returns `(:a :b :c)`. This is a tuple of symbols, isn’t it? I guess that `Expr(:tuple, cs...)` is a tuple of symbols too. Why did `cs` fail?

---

<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:** [November 29, 2017, 2:41pm UTC](https://discourse.julialang.org/t/how-to-use-destructuring-assignment-with-macro/7385/4 "2017-11-29T14:41:53Z")

</div>

```julia
julia> dump(:((:a,:b,:c)))
Expr
  head: Symbol tuple
  args: Array{Any}((3,))
    1: QuoteNode
      value: Symbol a
    2: QuoteNode
      value: Symbol b
    3: QuoteNode
      value: Symbol c
  typ: Any

```

vs

```julia
julia> dump(Expr(:tuple, :a, :b, :c))
Expr
  head: Symbol tuple
  args: Array{Any}((3,))
    1: Symbol a
    2: Symbol b
    3: Symbol c
  typ: Any

```

If you find [Julia AST](https://docs.julialang.org/en/latest/devdocs/ast/)s confusing, you are not alone 😄

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [November 29, 2017, 2:45pm UTC](https://discourse.julialang.org/t/how-to-use-destructuring-assignment-with-macro/7385/5 "2017-11-29T14:45:30Z")

</div>

😃 This one had me scratching my head:

```julia
julia> dump(:(a,b,c = 1,2,3))
Expr
  head: Symbol tuple
  args: Array{Any}((5,))
    1: Symbol a
    2: Symbol b
    3: Expr
      head: Symbol =
      args: Array{Any}((2,))
        1: Symbol c
        2: Int64 1
      typ: Any
    4: Int64 2
    5: Int64 3
  typ: Any

```

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [November 29, 2017, 2:51pm UTC](https://discourse.julialang.org/t/how-to-use-destructuring-assignment-with-macro/7385/6 "2017-11-29T14:51:02Z")

</div>

> [@ta2gch](#):
>
> What difference is it between cs and Expr(:tuple, cs…)?

Julia does not do left-hand-side destructuring on tuples (which `cs` is); it does destructuring on `Expr` objects. It _is_ confusing, but not much can be done about it. As Stefan said, Julia suffers from “the curse of syntax”.

---

<div class="post-metadata">

**Author:** ![ta2gch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ta2gch/32/10663_2.png) [@ta2gch](https://discourse.julialang.org/u/ta2gch)\
**Post date:** [November 29, 2017, 3:04pm UTC](https://discourse.julialang.org/t/how-to-use-destructuring-assignment-with-macro/7385/7 "2017-11-29T15:04:56Z")

</div>

I got it. Macros works on Expr which is **not** Tuple, of cause, and is not Array too. To write macro in Julia, I have to takes care of Expr only,

---

<div class="post-metadata">

**Author:** ![ta2gch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ta2gch/32/10663_2.png) [@ta2gch](https://discourse.julialang.org/u/ta2gch)\
**Post date:** [November 29, 2017, 3:13pm UTC](https://discourse.julialang.org/t/how-to-use-destructuring-assignment-with-macro/7385/8 "2017-11-29T15:13:56Z")

</div>

I saw that. My saying was wrong, the first is a tuple of **quoted** symbol, isn’t it? Expr doesn’t quote its arguments like `(:a :b :c)`, while `:` quotes its arguments like `(:(:a), :(:b), :(:c))`. Julia’s expanding rules confuse me, but your link is so helpful for me. Thank you!

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [November 29, 2017, 4:52pm UTC](https://discourse.julialang.org/t/how-to-use-destructuring-assignment-with-macro/7385/9 "2017-11-29T16:52:34Z")

</div>

In general it is always much more robust, precise, and reliable to use the `Expr` constructor, so I recommend always trying out `dump` and then using the constructor if you want to do reliable metaprogramming.

---

<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:** [November 29, 2017, 5:39pm UTC](https://discourse.julialang.org/t/how-to-use-destructuring-assignment-with-macro/7385/10 "2017-11-29T17:39:53Z")

</div>

> [@chakravala](#):
>
> always much more robust, precise, and reliable to use the Expr constructor

I generally think the opposite; since I am not sure how stable the internal representation of the AST is going to be, I am always reluctant to use `Expr`, and prefer when something else is available (eg `Meta.quot`, splicing into expressions, etc).

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [November 29, 2017, 6:21pm UTC](https://discourse.julialang.org/t/how-to-use-destructuring-assignment-with-macro/7385/11 "2017-11-29T18:21:24Z")

</div>

> [@Tamas\_Papp](#):
>
> I generally think the opposite; since I am not sure how stable the internal representation of the AST is going to be

My experience is different. `Expr` seems to be more reliable. For example, when `abstract Name` was changed to `abstract type Name end`, the `Expr(:abstract,:Name)` would still work in both the old and new versions of Julia, so therefore the `Expr` way of doing it is more reliable and robust in the long run.
