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))
│ (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
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!