# Destructuring syntax in julia 1.7

**URL:** <https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236>\
**Category:** Internals & Design\
**Tags:** destructuring\
**Created:** [September 15, 2021, 11:01pm UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236 "2021-09-15T23:01:36Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![xfcjscn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xfcjscn/32/19613_2.png) [@xfcjscn](https://discourse.julialang.org/u/xfcjscn)\
**Post date:** [September 15, 2021, 11:01pm UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/1 "2021-09-15T23:01:36Z")

</div>

1.7 introduced new language feature:  
`(; a, b) = x` can now be used to destructure properties `a` and `b` of `x` . This syntax is equivalent to `a = getproperty(x, :a); b = getproperty(x, :b)`

From a reader perspective(much more compare to writer perspective in action), I can not appreciate the elegance of this syntax. It’s too not “mathematical”.  
Existing argument destructuring for tuple is much elegant as there is an isomorphism between the delcare structure and the data structure.  
Why this new syntax don’t have this feature?

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [September 15, 2021, 11:28pm UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/2 "2021-09-15T23:28:20Z")

</div>

> [@xfcjscn](#):
>
> Existing argument destructuring for tuple is much elegant as there is an isomorphism between the delcare structure and the data structure.  
> Why this new syntax don’t have this feature?

It does, `(; a, b)` creates a `NamedTuple` just as `(a, b)` creates a `Tuple`. Note however that just as regular destructuring doesn’t just work with tuples but with any iterable, property destructuring also works with any objects that have fields.

---

<div class="post-metadata">

**Author:** ![xfcjscn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xfcjscn/32/19613_2.png) [@xfcjscn](https://discourse.julialang.org/u/xfcjscn)\
**Post date:** [September 16, 2021, 12:09am UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/3 "2021-09-16T00:09:49Z")

</div>

A surprise, I didn’t know (; a = 1, b =2) can create a named tuple. 😀  
I read out the manual, not found this. It’s not mentioned in manual right?

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [September 16, 2021, 12:20am UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/4 "2021-09-16T00:20:10Z")

</div>

It is mentioned in the docstring at least: [Essentials · The Julia Language](https://docs.julialang.org/en/v1/base/base/#Core.NamedTuple)

---

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [September 16, 2021, 3:58am UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/5 "2021-09-16T03:58:59Z")

</div>

TIL, thanks. Does this mean `UnPack.jl` isn’t necessary anymore? This seems equivalent

---

<div class="post-metadata">

**Author:** ![xfcjscn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xfcjscn/32/19613_2.png) [@xfcjscn](https://discourse.julialang.org/u/xfcjscn)\
**Post date:** [September 16, 2021, 4:29am UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/6 "2021-09-16T04:29:05Z")

</div>

I see, thanks

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [September 16, 2021, 5:11am UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/7 "2021-09-16T05:11:30Z")

</div>

Personally, I feel a bit uncomfortable that the names on the left hand side influence which values are read on the right hand side.

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [September 16, 2021, 6:12am UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/8 "2021-09-16T06:12:46Z")

</div>

But that’s the point isn’t it? So you can write

```julia
(; height, weight) = df

```

to extract two columns, and you don’t have to know/care about other columns or the order of these two columns in `df`.

@xfcjscn note that the “isomorphism” goes further as the syntax can also be used with existing variables:

```julia
a = 1
b = 2

nt = (; a, b)

```

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [September 16, 2021, 6:28am UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/9 "2021-09-16T06:28:42Z")

</div>

> [@jishnub](#):
>
> TIL, thanks. Does this mean `UnPack.jl` isn’t necessary anymore? This seems equivalent

> <https://github.com/mauro3/UnPack.jl/issues/14>
>
> Property destructuring was just merged into master :tada: https://github.com/Ju…liaLang/julia/pull/39285 
> 
> Would be nice if this package allowed you to match that syntax, i.e. if in addition to the current form, it also allowed:
> 
> \`\`\`julia
> @unpack (;x, y) = foo
> \`\`\`
> 
> such that in the future one can upgrade by just dropping the \`@unpack\`.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [September 16, 2021, 6:32am UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/10 "2021-09-16T06:32:39Z")

</div>

> [@sijo](#):
>
> But that’s the point isn’t it?

Of course it’s the point, but it feels ‘magical’, like a macro, or ‘spooky action at a distance’.

Shouldn’t the specification of which fields to read be on the RHS, not the LHS?

I feel similarly about the kwarg thing, where

```julia
foo(;kw) 

```

is the same as

```julia
foo(;kw=kw) 

```

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [September 16, 2021, 7:04am UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/11 "2021-09-16T07:04:01Z")

</div>

Ah I see your point. But I wouldn’t say it’s like macros: there are arbitrary syntax rules. This follows the rules, while macros allow you to bend the rules.

I think it’s a matter of habit. Probably if we had spent years writing `NamedTuple([:a=>1, :b=>2])` we would think `(a=1, b=2)` is magical, but it’s just new syntax. For me it’s now quite natural to write `plot(x, y; linewidth)`.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [September 16, 2021, 7:14am UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/12 "2021-09-16T07:14:01Z")

</div>

> [@sijo](#):
>
> This follows the rules, while macros allow you to bend the rules.

It follows the syntax rules because the rules were changed 😉 The reason I bring up macros is that it looks like this _ought_ to have a macro in front of it, like `@destructure (;a, b) = x` or `@splat foo(;kw)`

What I don’t like about it is that the _name choices_ you make for variables enable special syntax. The syntax wouldn’t work if I wanted to destructure fields `:a` and `:b` into variables `x` and `y`. Similarly with kwargs.

(BTW, it’s not a big deal, really, but this thread made me come out with it now.)

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [September 16, 2021, 7:54am UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/13 "2021-09-16T07:54:03Z")

</div>

> [@DNF](#):
>
> The syntax wouldn’t work if I wanted to destructure fields `:a` and `:b` into variables `x` and `y` .

That would require specifying the source _and_ target names. The main motivation I think was precisely to avoid this repetition when you want to keep the same names.

Having the field specification on the “name binding” side is actually what makes the syntax so useful. Consider these cases:

```julia
for (; x, y) in eachrow(df)
    println("x-y = $(x-y)")
end

map(eachrow(df)) do (; x, y)
    x-y
end

```

I don’t know how that would work if the syntax was on the “RHS” (meaning `eachrow(df)` here).

Also I’m not sure you could implement this with a macro. I think it’s really the kind of thing where you need syntax.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [September 16, 2021, 8:06am UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/14 "2021-09-16T08:06:31Z")

</div>

> [@sijo](#):
>
> That would require specifying the source _and_ target names. The main motivation I think was precisely to avoid this repetition when you want to keep the same names.

I understand the purpose and the advantage, and I have no alternative suggestion to make it work otherwise. It just feels ‘magical’, and I don’t like it, and I wish it wouldn’t work at all, no matter how useful and practical it is.

I don’t dislike it _very strongly_, but I’m not a fan.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [September 16, 2021, 8:06am UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/15 "2021-09-16T08:06:39Z")

</div>

The obvious extension to this syntax is `(; foo = a, bar = b) = x`, of course 😛

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [September 16, 2021, 12:19pm UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/16 "2021-09-16T12:19:50Z")

</div>

> [@sijo](#):
>
> `(; height, weight) = df`

Is this already working for dataframes?

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [September 16, 2021, 12:38pm UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/17 "2021-09-16T12:38:06Z")

</div>

Yes there’s nothing special that DataFrames.jl needs to do: in general `(; a, b) = x` will do `a = x.a` and `b = x.b`. You can write e.g. `a = df.a` so it works.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [September 16, 2021, 12:42pm UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/18 "2021-09-16T12:42:54Z")

</div>

Really cool.  
_NB: got confused because the command prints the whole dataframe but the variables are well assigned indeed._

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 16, 2021, 1:47pm UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/19 "2021-09-16T13:47:35Z")

</div>

> [@DNF](#):
>
> The reason I bring up macros is that it looks like this _ought_ to have a macro in front of it, like `@destructure (;a, b) = x`

This is what the `@unpack` macro from parameters does and looks like. I use it, but I agree in general with you, one has to be careful to keep the code understandable using that syntax. (I like that `@unpack` is more verbose, I would like to see that merged into base, but I’m not sure if it can be used everywhere where the new destructuring syntax is used, I guess it does not).

---

<div class="post-metadata">

**Author:** ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)\
**Post date:** [September 16, 2021, 1:56pm UTC](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236/20 "2021-09-16T13:56:26Z")

</div>

> [@simeonschaub](#):
>
> It does, `(; a, b)` creates a `NamedTuple` just as `(a, b)` creates a `Tuple` .

Ah, suddenly I am almost reconciled with the `(; a, b)` way of creating tuples!

[Next page](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236.md?page=2)
