Stream: announcements

Topic: nominal field ordering is now preserved


view this post on Zulip Richard Feldman (Jun 21 2026 at 11:17):

this is almost exclusively interesting to people working on platforms, but: we now preserve nominal field ordering (instead of reordering them by alignment and alphabetically by field name) as long as this wouldn't result in any alignment padding. (see #show and tell > Roc TigerBeetle Client for original motivation).

this is a breaking change for platform authors because if you were sending nominal types to/from the host, they may have a different layout now :sweat_smile:

view this post on Zulip Richard Feldman (Jun 21 2026 at 11:21):

if you write a nominal type in a way that would need alignment padding, we still reorder to not need padding, because if we didn't do that, it would mean you'd have to micromanage field order to get optimal memory usage, which would be bad

view this post on Zulip Richard Feldman (Jun 21 2026 at 11:22):

that said, if you need to interface with a host that has alignment padding, you can use unnamed fields (e.g. _padding1: U32 or even just _ : U32) in the nominal record definition and those won't get compiled away

view this post on Zulip Richard Feldman (Jun 21 2026 at 11:23):

so this way, if you're not trying to match a particular host field ordering, you still get the "automatically sorted by alignment, so we aren't wasting any memory on padding" behavior as before...but also, if you specify a field ordering that wouldn't need any padding, then you can have the order match what the host wants exactly

view this post on Zulip Richard Feldman (Jun 21 2026 at 11:23):

this is on main but I haven't updated roc glue for it yet, because I just remembered to do that while writing this announcement :joy:

view this post on Zulip Richard Feldman (Jun 21 2026 at 11:23):

I'll make a PR for that next!

view this post on Zulip Bryce Miller (Jun 21 2026 at 14:58):

Were the unnamed fields a thing before? I thought I had come up with such a nice solution by creating custom number types that could only be 0 for my reserved/padding fields. Then you went and gave me an even better language feature :sweat_smile:

view this post on Zulip Richard Feldman (Jun 21 2026 at 15:02):

I added those in the same PR :smile:

view this post on Zulip Richard Feldman (Jun 21 2026 at 15:03):

seemed like a clear need once we're preserving ordering!

view this post on Zulip Richard Feldman (Jun 21 2026 at 15:03):

lmk if you run into any problems with this, and thanks for sharing the original motivating use case! :smiley:

view this post on Zulip Bryce Miller (Jun 21 2026 at 15:09):

Sweet, I’m hoping to give it a whirl sometime later today!

view this post on Zulip Bryce Miller (Jun 21 2026 at 21:06):

This appears to be working for me!

view this post on Zulip Oskar Hahn (Jun 23 2026 at 05:36):

I like this change. When I first tried writing a platform, the field reorder was hard.

But I don't understand the new system, if there is padding. Could you give some examples?

In my cases, I did not have types in the platform, that I wanted to convert to roc, but the other way around. I had roc types like a http-request or http-responce, that I had to convert to the host language. Is this something, roc-type-developers have to be aware of? Should the fields of roc types be in a order, they can be converted to a host language, without field reorder?

view this post on Zulip Richard Feldman (Jun 23 2026 at 12:18):

the basic idea is:

view this post on Zulip Richard Feldman (Jun 23 2026 at 12:19):

does that make sense?

view this post on Zulip Oskar Hahn (Jun 24 2026 at 05:48):

My question is about this part of the announcement:

Richard Feldman said:

if you write a nominal type in a way that would need alignment padding, we still reorder to not need padding, because if we didn't do that, it would mean you'd have to micromanage field order to get optimal memory usage, which would be bad

How does this reorder look like, if it is necessary:

For example, if you want to return a type like this to the platform:

{
  f2: U8,
  f1: U8,
  f3: U8,
  f4: U16,
}

You could move f4 to the top (the old system). Or you could switch it with f3 to keep the nominal field order of f1 and f2.

I think, there are many strategies, how you can do the field reorder if necessary. I would like to know, what strategy you choose.


Last updated: Jul 23 2026 at 13:15 UTC