Could commas be optional at end of line, like semicolons?

The syntax of the Typst scripting language is very enjoyable. One thing that keeps coming up for me personally though is the necessity for putting commas even in multi-line arrays, dictionaries, and function calls.

So the question is this: Would it be possible (and desirable) to change the syntax such that the following snippet:

#rect(
  height: 100%,
  width: 100%,
  fill: aqua
)

Could be written as:

#rect(
  height: 100%
  width: 100%
  fill: aqua
)

This would mean that commas need to be used only where multiple values occur per line, meaning linebreaks would also act as value separator, as with semicolons and “statements”. If this is possible, it would make the syntax even more lightweight and enjoyable to use, in my opinion.

What do others think of this? :slight_smile:

To be honest, I don’t think so. Because once when you’d like to refractor your code from something like

#rect(
  height: 100%
  width: 100%
  fill: aqua
)

To

#rect(height: 100%, width: 100%, fill: aqua)

You would retype all the commas. It would be annoying, trust me.

1 Like

What is problematic about this, is that (...) is also used for grouping multi-line expressions (code blocks cannot be used for this precisely because the semicolons can be omitted in favor of line breaks). This means something like this works:

let val = (
  "one"
    + "two"
)

assert.eq(val, "onetwo")

With your proposal, however, this would become an array and then there would be no way at all to have a multiline expression.

1 Like

That’s true.

Which of these is better (always commas vs sometimes commas) is of course a matter of opinion. I’d happily reintroduce commas if I could omit them most of the time.

Thanks for making that valid point though!

Ah, that’s a good point. I understand that this issue alone means that we are unlikely to see a change here, as it might cause some disruption wherever multiline expressions are in use currently. I was unaware of the issue probably because I never felt the need (in my very limited experience with Typst) to use them.

I’d like to entertain the thought just a little more, to better understand whether this would really not be possible at all, or why even I would not want this after all:

The case above and similar ones could be handled by only interpreting linebreaks as commas where that is syntactically valid, right? – Admittedly, that’d be a weird feature. (Isn’t there some programming language having this though?!)

In any case, this problem could be handled by explicit line continuation, e.g. like a slash at the end of the line as in Python, correct? Whether that’s preferrable though is of course another question entirely.

Thanks for replying!

Oh and, I forgot to say: I already have a similar annoyance now, because I follow the general style of putting commas in each line, including the last line, in multiline situations (especially arrays). That means adding or removing that last comma whenever changing to multiline or singleline respectively.

And just not putting that last comma also has cons, namely that reordering the arguments or values then requires adding and removing commas, also annoying.

I wonder whether there is a good solution to this in general…

A better solution is to support putting a comma after each line no matter whether it is the last argument or not, like Python.

That’s already supported.

No, that would not be enough. unary plus and unary minus are supported operators, so even the exact example Laurenz made would still be interpreted as an array. (+ "two" is a type error, but syntactically no problem)

For semicolons, there are; the book Crafting Interpreters lists some in a design note:

Python treats all newlines as significant unless an explicit backslash is used at the end of a line to continue it to the next line. […] This rule works well for Python because it is a highly statement-oriented language.

(Typst is very expression-oriented)

JavaScript’s “automatic semicolon insertion” rule is the real odd one. Where other languages assume most newlines are meaningful and only a few should be ignored in multi-line statements, JS assumes the opposite. […]

This design note would turn into a design diatribe if I went into complete detail about how that even works, much less all the various ways that JavaScript’s “solution” is a bad idea. It’s a mess. […]

The design note also says “If you’re designing a new language, you almost surely should avoid an explicit statement terminator” – but that advice can’t very easily be applied to commas, and Typst did avoid mandatory semicolons.

1 Like

@Aegon You probably meant “support putting a comma after the last argument”. That’s indeed supported, and I use it almost always, as mentioned above:

You are correct. It would require somehow detecting errors other than syntax errors, and that would definitely be way too weird. I would not want that either. (And it would still not solve the problem of having arrays of numbers, including negative numbers, vs subtraction.)

Thanks a lot for that link! I see that such “magic” as in JS is probably a bad idea (“weird”), as I have stated above. Though I don’t see why it shouldn’t be in principle possible to do something similar with commas. But it might require significant changes in grammar… See next post.

The main reason “optional commas” would not work cleanly:

I think the main problem isn’t multiline expressions though (which could be solved by explicit line continuation via backslash at EOL for example), but that array construction in the current grammar really needs commas:

// a is a string
let a = "foo"

// b should also be a string
let b = ("foo")

// c would be an array of two strings if EOL commas were optional
let c = (
  "foo"
  "bar"
)

// What should this be however? string or single-element array?
let d = (
  "foo"
)

So the overload of () as array constructor, and/or some other far-reaching changes to grammar would have to be implemented, and I see that this is out of scope for Typst. This then answers my original question :slight_smile:

Thanks to @laurmaedje, @SillyFreak and @Aegon for replying.

Thanks for telling me this.