Is set basically syntactic sugar for deepcopying a struct, mutating the specified field, and then returning that deepcopy? Seems like it could be quite slow.

Yes. I’m not sure how slow it is in Julia, but pure functional languages do tend to generate more garbage for this reason. Hopefully the compiler can optimize it away in simple cases.

Edit: It’s not deepcopying the whole struct, just the parts that need to point to something new. So if you update a.b.c, it will shallow-copy a and a.b, but nothing else.