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"
)
}
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"
}
notice the lack of commas in between fields
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
(currently it looks for a comma, but that's actually redundant; the comma must always be followed by either another field label or a })
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"
}
however, I don't like this as much because:
_ -> "other",?) so if it's required, the errors could be confusing_ -> "other",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.
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 }
my initial reaction is that I prefer the first one, but honestly I bet I'd get used to the second one very quickly
so, to summarize - the idea would be:
thoughts?
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.
I don’t like not having commas for single line records.
Yeah, me too. The commas also simplify things for autocomplete in the editor.
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
}
interesting ideas!
so then the rule could be "record field entries are separated by either commas or outdents"
Yeah, I guess so.
so then the rule could be "record field entries are separated by either commas or outdents"
That looks so annoyingly inconsistent :p
as in the code snippet looks annoyingly inconsistent?
because of commas in some places but not others
Yes
it doesn't bother me personally, but I can see that point of view
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
I like that better, I do feel like users could get annoyed with getting an error for using a comma in a multiline record.
what if we had the parser accept it but then the formatter removes it?
so the rule would be stylistic rather than giving compiler errors
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...
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 previousblah: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
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"
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
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:
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".
I personally like the current parentheses version. It just seems clear to me and I don't see a reason to change it
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