Destructuring & setindex!

I discovered this just a few weeks ago myself when I had an occasion to update two refs at the same time like this. I wasn’t sure if it would do what I wanted so I checked the lowering and was happy to discover that it did.

It’s even recursive into nested tuples.

julia> Meta.@lower a.x, b[], (c.y, d[]) = (1,2, (3,4))
:($(Expr(:thunk, CodeInfo(
...
│         (Base.setproperty!)(a, :x, %12)
│         (Base.setindex!)(b, %3)
...
│         (Base.setproperty!)(c, :y, %24)
...
│         (Base.setindex!)(d, %28)

Even more obliquely, it’s even allowed to define limited functions this way:

julia> f(), g(), x+y = 1:3
1:3

julia> f()
1

julia> g()
2

julia> 1+1
3

Of course, we cannot do anything more interesting than constant-valued functions since the RHS is an immediately-evaluated value and not a function body.

Looking at the lisp, it looks like tuple destructuring is implemented exactly as a loop that generates the same code as a sequence of assignments for each thing on the LHS while iterating over the RHS. And I think it’s something you can count on as it’d be an error otherwise. Let’s document it!

4 Likes