Stream: ideas

Topic: Update nested record field


view this post on Zulip Nikita Mounier (Apr 09 2022 at 19:24):

What do you think about being able to update nested records' fields? Aka to be able to do this:

User : {
    info : {
        personal: {
            age: U8,
            # ...
        professional: {
            # ...
        },
        # ...
    },
    # ...
}
birthday : User -> User
birthday = \user ->
    { user & info & personal & age: user.info.personal.age + 1 }

Coming from the C-style language world (Swift), it seems like quite a basic and necessary operation, and I'm surprised that Elm doesn't support this given it likes having one big record with many nested records describing its state.
This is the syntax I naturally went for when I didn't know that this isn't supported. What do you think?

view this post on Zulip Kesanov (Apr 09 2022 at 19:35):

The syntax does not make sense. This would be more reasonable:

birthday = \user -> { user.info.personal & age: age + 1 }

view this post on Zulip Brendan Hansknecht (Apr 09 2022 at 19:35):

I assume the syntax would more likely be something like this?

{ user & info.personal.age: user.info.personal.age + 1 }

view this post on Zulip Brendan Hansknecht (Apr 09 2022 at 19:36):

:point_up: Same thought more or less

view this post on Zulip Nikita Mounier (Apr 09 2022 at 19:38):

Hmmmm, to me updating a field in a record means updating the whole record (adhering to value semantics), which is why multiple &s seemed natural to me – but maybe that's just me though. @Brendan Hansknecht seems like the next best thing for me, since there's still this idea of updating the whole record.

view this post on Zulip Brendan Hansknecht (Apr 09 2022 at 19:39):

Currently, I think this would be the required syntax:

{ user & info: { info & personal: { personal & age: age + 1 } } }

view this post on Zulip Brendan Hansknecht (Apr 09 2022 at 19:40):

The issue with many &s is that they don't really suggest digging deeper into a record. They more suggest selecting mutliple fields from the highest level of a record. Though I guess I see what you mean.

view this post on Zulip Martin Stewart (Apr 09 2022 at 19:40):

I'm surprised that Elm doesn't support this given it likes having one big record with many nested records describing its state.

For some context, the reason Elm doesn't allow nested record updates is because it wants to push the user towards instead creating less nested data structures and using opaque types with helper functions to modify state.

view this post on Zulip Nikita Mounier (Apr 09 2022 at 19:44):

Brendan Hansknecht said:

The issue with many &s is that they don't really suggest digging deeper into a record. They more suggest selecting mutliple fields from the highest level of a record.

No yeah that's absolutely fair, I see what you mean.

For what's it's worth, I tried the current required syntax but got a compiler panic (something about unreachable code inside compiler/mono/src/borrow.rs).

view this post on Zulip Nikita Mounier (Apr 09 2022 at 19:44):

For some context, the reason Elm doesn't allow nested record updates is because it wants to push the user towards instead creating less nested data structures and using opaque types with helper functions to modify state.

Is Roc also trying to be this opinionated about data modelling? What do you think?

view this post on Zulip Brendan Hansknecht (Apr 09 2022 at 19:46):

I think I have to answer yes even though I don't think it is in the same way or scale of elm. I think these sorts of ML languages really put a focus on data modeling in very opinionated ways.

view this post on Zulip Brendan Hansknecht (Apr 09 2022 at 19:51):

I definitely think the common approach to nested records in ML languages is that records only nest if they are a unit of data that will be accessed and used together. If that is the case, the data will have its own set of modification functions. Since the data has its own modification functions, there is no need to do nested record updates. Just { myrecord & mySubRecord: updateMySubRecord data }.

view this post on Zulip Brendan Hansknecht (Apr 09 2022 at 19:52):

All that being said, I am totally open to nested record update syntax. I think it would likely come in handy at some points, but I do agree that it may lead to worse data design for some users. So no idea if the tradeoff is worth it. I mostly program in C++ and rarely use nested records that aren't fully wrapped types. So even in C++ I think it is a feature I don't use super often.

view this post on Zulip Nikita Mounier (Apr 09 2022 at 21:23):

Yeah, I think nested records update syntax should be in Roc, since it's aiming to be a general-purpose language. Although it's strongly opinionated about mutability and side effects (by design), I'm not sure if it needs to be as opinionated about data modelling (at least not at the level of elm).

view this post on Zulip Brendan Hansknecht (Apr 09 2022 at 21:44):

This isn't just the level of elm. For example, I don't think ocaml nor F#(except through c# capatability maybe) have nested record update and they are general purpose language.

view this post on Zulip Brendan Hansknecht (Apr 09 2022 at 21:45):

I think most ML languages don't have it in general

view this post on Zulip Kevin Gillette (Apr 09 2022 at 23:40):

Within FP, I'm not very familiar with typical data modeling tradeoffs... When are nested records valuable, and particularly when is it desirable to access fields directly that are multiple layers deep?

view this post on Zulip Notification Bot (Apr 09 2022 at 23:58):

This topic was moved here from #contributing > Update nested record field by Richard Feldman.

view this post on Zulip Richard Feldman (Apr 10 2022 at 00:00):

what do you think of this? https://github.com/rtfeldman/roc/issues/1588

view this post on Zulip Nikita Mounier (Apr 10 2022 at 00:17):

Ugh, I can't believe I forgot to search through the GitHub issues first, that's my bad.

view this post on Zulip Nikita Mounier (Apr 10 2022 at 00:27):

But yeah, that looks really good to me. I think it's fine if there's a little verbosity when using the previous value to make the new one, it's the same as in any other language. Also the performance benefits look really neat!

view this post on Zulip Richard Feldman (Apr 10 2022 at 00:35):

no worries!


Last updated: Jun 16 2026 at 16:19 UTC