Subscribe:   RSS icon   twitter icon

Struct Destructuring in Julia

Lee Phillips
October 7th, 2021

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.


Share with Facebook Share with Twitter Share with Reddit Share with Slashdot
▶ Comment
lee-phillips.org is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to amazon.com.
Quotilizer ... loading ...

Tenuously related:

The best tool for CVs with publication lists.