Stream: ideas

Topic: delimiters between record fields


view this post on Zulip Richard Feldman (Mar 22 2023 at 15:51):

something I've noticed about records which take functions (e.g. event handlers) is that writing inline lambdas for them is annoying because it requires parentheses:

things = {
    blah: Foo,
    bar: "stuff",
    onWhatever:
        (
            \event, arg2 ->
                when event is
                    Whatever -> "whatever"
                    _ -> "other"
        ),
    onSomething:
        (
            \event, arg2 ->
                when event is
                    Something -> "something"
                    _ -> "other"
        )
}

view this post on Zulip Richard Feldman (Mar 22 2023 at 15:51):

what if you could write this instead?

things = {
    blah: Foo
    bar: "stuff"
    onWhatever:
        \event, arg2 ->
            when event is
                Whatever -> "whatever"
                _ -> "other"
    onSomething:
        \event, arg2 ->
            when event is
                Something -> "something"
                _ -> "other"
}

view this post on Zulip Richard Feldman (Mar 22 2023 at 15:52):

notice the lack of commas in between fields

view this post on Zulip Richard Feldman (Mar 22 2023 at 15:52):

the idea is that we use the fields themselves as the separator - e.g. when the parser sees bar: it knows that we must be done with the previous blah: definition

view this post on Zulip Richard Feldman (Mar 22 2023 at 15:53):

(currently it looks for a comma, but that's actually redundant; the comma must always be followed by either another field label or a })

view this post on Zulip Richard Feldman (Mar 22 2023 at 15:54):

I think we could also theoretically look for a trailing comma instead of requiring parens, like so:

things = {
    blah: Foo,
    bar: "stuff",
    onWhatever:
        \event, arg2 ->
            when event is
                Whatever -> "whatever"
                _ -> "other",
    onSomething:
        \event, arg2 ->
            when event is
                Something -> "something"
                _ -> "other"
}

view this post on Zulip Richard Feldman (Mar 22 2023 at 15:55):

however, I don't like this as much because:

view this post on Zulip Richard Feldman (Mar 22 2023 at 15:56):

a thing to consider with this idea: if we didn't have commas, would they become optional? That seems probably fine to me; the formatter could then remove them as a matter of style.

view this post on Zulip Richard Feldman (Mar 22 2023 at 15:57):

but then there's the question: what should the style be for single-line records? e.g. compare:

point = { x: 1, y: 2, z: 3 }
point = { x: 1 y: 2 z: 3 }

view this post on Zulip Richard Feldman (Mar 22 2023 at 15:57):

my initial reaction is that I prefer the first one, but honestly I bet I'd get used to the second one very quickly

view this post on Zulip Richard Feldman (Mar 22 2023 at 15:58):

so, to summarize - the idea would be:

view this post on Zulip Richard Feldman (Mar 22 2023 at 15:58):

thoughts?

view this post on Zulip Nick Hallstrom (Mar 22 2023 at 16:03):

What if the separator needs to be a comma OR a newline? That way what you have for the lambdas with no commas works, but it also avoids point = { x: 1 y: 2 z: 3 } from being valid. Because my initial reaction is the same, I don’t like not having commas for single line records.

view this post on Zulip Anton (Mar 22 2023 at 16:05):

 I don’t like not having commas for single line records.

Yeah, me too. The commas also simplify things for autocomplete in the editor.

view this post on Zulip Brendan Hansknecht (Mar 22 2023 at 16:09):

I think that either we should follow as nick said above or maybe make indenting important to this.

things = {
    blah: Foo, # Inline, comma required
    bar:
        # This body is indented. No comma needed (maybe totally ban comma?)
        "stuff"
    onWhatever:
        # Same here
        \event, arg2 ->
            when event is
                Whatever -> "whatever"
                _ -> "other"
    onSomething: \event, arg2 -> "other", # inline, requires a comma
}

view this post on Zulip Richard Feldman (Mar 22 2023 at 16:10):

interesting ideas!

view this post on Zulip Richard Feldman (Mar 22 2023 at 16:11):

so then the rule could be "record field entries are separated by either commas or outdents"

view this post on Zulip Brendan Hansknecht (Mar 22 2023 at 16:12):

Yeah, I guess so.

view this post on Zulip Anton (Mar 22 2023 at 16:15):

so then the rule could be "record field entries are separated by either commas or outdents"

That looks so annoyingly inconsistent :p

view this post on Zulip Richard Feldman (Mar 22 2023 at 16:16):

as in the code snippet looks annoyingly inconsistent?

view this post on Zulip Richard Feldman (Mar 22 2023 at 16:16):

because of commas in some places but not others

view this post on Zulip Anton (Mar 22 2023 at 16:17):

Yes

view this post on Zulip Richard Feldman (Mar 22 2023 at 16:18):

it doesn't bother me personally, but I can see that point of view

view this post on Zulip Richard Feldman (Mar 22 2023 at 16:19):

I wouldn't mind a rule of "single-line record field labels are separated by commas, multi-line record fields are separated by newlines" and you can't mix and match

view this post on Zulip Anton (Mar 22 2023 at 16:21):

I like that better, I do feel like users could get annoyed with getting an error for using a comma in a multiline record.

view this post on Zulip Richard Feldman (Mar 22 2023 at 16:23):

what if we had the parser accept it but then the formatter removes it?

view this post on Zulip Richard Feldman (Mar 22 2023 at 16:24):

so the rule would be stylistic rather than giving compiler errors

view this post on Zulip Anton (Mar 22 2023 at 16:33):

It's better, but not requiring commas does make things significantly more complicated for the editor's autocomplete.
With a comma, it's easy to know that we're going into "new field" or "end of record". If an enter could lead you to a new record field, I think it becomes complicated to figure out if you want a new field, or an indented function argument, or another when branch...

view this post on Zulip dank (Mar 22 2023 at 16:41):

Richard Feldman said:

the idea is that we use the fields themselves as the separator - e.g. when the parser sees bar: it knows that we must be done with the previous blah: definition

what if you got an inner record defined in the lambda? or an annotation?
well inner record is more easily detectable because of {

personally haskell style of commas to the left isn't so bad
it's a bit bad haha
but not that bad

view this post on Zulip Georges Boris (Mar 22 2023 at 16:56):

I'm not sure my comment will be constructive but I love how Nix handles lists and records... is so consistent tho you could argue the need for ; everywhere can clutter things. But I like how lists can just be:

[ foo bar ]
[
  foo
  bar
]

and records can be:

{ foo = bar; bar = foo; }
{
  foo = bar;
  bar = foo;
}

I'm having a hard time thinking about a similar solution for lambdas... but the trailing , on multiline defs is certainly hard to notice - but it could easily be added through the formatter? I'm not a fan on having things that are defined as "it works this way _except when condition x_ then it works this new way"

view this post on Zulip Richard Feldman (Mar 22 2023 at 17:13):

Anton said:

It's better, but not requiring commas does make things significantly more complicated for the editor's autocomplete.
With a comma, it's easy to know that we're going into "new field" or "end of record". If an enter could lead you to a new record field, I think it becomes complicated to figure out if you want a new field, or an indented function argument, or another when branch...

I could be wrong, but I think we can tell this in the editor because we know the expression ended

view this post on Zulip Richard Feldman (Mar 22 2023 at 17:13):

oh I guess that's hard to tell if you're in a when because you don't know if there's another branch coming next :thinking:

view this post on Zulip Pit Capitain (Mar 22 2023 at 17:54):

Brendan Hansknecht said:

I think that either we should follow as nick said above or maybe make indenting important to this.

things = {
    blah: Foo
    bar:
       ...

I don't know the Roc parser, but couldn't we automatically parse an implicit indent after "blah:" and an outdent between "Foo" and "bar:"? Then this code would satisfy the rule "record field entries are separated by either commas or outdents".

view this post on Zulip Seth Workman (Mar 22 2023 at 17:56):

I personally like the current parentheses version. It just seems clear to me and I don't see a reason to change it

view this post on Zulip Joshua Warner (Mar 22 2023 at 19:54):

I would suggest that, whatever we land on, the rules should be consistent across records, lists and tuples.


Last updated: Jun 16 2026 at 16:19 UTC