Struct Destructuring in Julia
Two days ago LWN published my article about the new features arriving with version 1.7 of Julia. One new syntax feature that I only had space to treat briefly is a new form of destructuring. Here I want to explain in more detail why this can be useful.
In Julia you can define a struct like this:
struct S
a
b
end
This is usually how we define new datatypes.
If we instantiate the struct with newS = S(4, 5), we can access the two properties of newS with newS.a and newS.b, which yield 4 and 5. This is existing syntax.
The new feature allows us to destructure this way:
(; a, b) = newS
Now a has the value 4 and b has the value 5.
The field names on the left must exist in the struct. Otherwise, you get an error:
(; a, x) = newS
ERROR: type S has no field x
This might seem at first glance to be of limited utility. In current Julia, you can already do this:
a, b = newS.a, newS.b
So the new syntax is a bit more concise.
However, the real advantage of the new destructuring may be in providing a succinct way to define functions that take keyword arguments.
The standard way to define a function that takes, say, one positional argument and two keyword arguments a and b is like this:
f(d; a, b) = (a + b)/d
And you call it with f(2; a=3, b=4), which yields 3.5.
But in the next version of Julia we can define it this way:
f2(d, (; a, b)) = (a + b)/d
This looks like it takes two positional arguments, but consider what happens if we make the call
f2(2, newS)
When the function interprets its arguments, d will get the value 2, and (; a, b) will get the value newS; but, with the new destructuring, this will assign 3 to a and 4 to b, so it’s the same as calling f(2; a=3, b=4). We can store other values for a and b in different instantiations of S, and pass them in to f2 as needed.
The new syntax can aid expressiveness, especially if you want to create a function that takes many keyword arguments. In practice, you may want to ensure that the struct you pass in has the right type by defining f2 this way:
f2(d, (; a, b)::S) = (a + b)/d

As I work on my Julia book I revisit completed chapters to update them with useful new features in the language and various packages as they come out or get close to release. In this way I hope that it will be as up-to-date, when it arrives, as a print book can be.

