Pitch: Eliding commas from multiline expression lists

Devil's advocate: We don't require consistency in the use of semicolons. And I think you could plausibly want to write a list like:

[
  short1, short2, short3, short4, short5
  someReallyLongItem(with: .lots, of: Complex(things))
  another.veryLong.item(with: Complications.different)
]
5 Likes

The example above you proposed to be treated as invalid is currently valid code.

I was very apprehensive about this proposal at first, but I think there have been some solid arguments that it’s very much in the spirit of Swift to remove unnecessary commas. That swayed me completely over to supporting this proposal. However, these examples demonstrate some very subtle and tricky corner cases which don’t come with an easy solution.

Either these examples are not worth addressing, and we can move ahead with a straightforward set of rules allowing comma elision, or they are, in which case we should acknowledge that comma elision is problematic and would introduce new footguns. But I think inventing additional carve-out rules specifically about these circumstances to exempt them from being eligible for comma elision is the worst of both worlds.

Personally, I’m leaning back towards the view that this change at this stage of Swift’s evolution brings more risks than benefits.

4 Likes

I was initially somewhat apprehensive about this change, but also curious to explore the benefits it might bring in some settings. @Douglas_Gregor’s post addressed some of the questions and concerns I had initially and as I’ve spent more time looking at comma-less code I’ve gotten much more comfortable with it.

I was especially curious about how EDSLs would benefit from this change (as has been discussed quite a bit already). After looking at a bunch of examples I am solidly in favor of this proposal and have been working with @nate_chandler to collect good examples.

There will certainly be ways to misuse this feature, but that is true of many features. Instead of rejecting this feature because it can be misused we should embrace it because it can lighten up the feel of declarative code in a meaningful way. We can address the potential for misuse by providing guidelines for effective use of this feature and cautions about uses that may lead to trouble.

4 Likes

Would you feel any better if the rule was revised so that trailing commas must be consistently included or omitted?

If we do include a rule a consistency requirement it would be a good idea to also introduce support for trailing commas after the last item of a comma-separated list. The consistency rule would be much easier to explain if this was allowed (and many of us have wanted this capability for independent reasons).

1 Like

That's a fair point. I think that's a nicely formatted list, though I worry that making the rule more complicated to allow it will make the rule less appealing.

That's true, I hadn't considered that :sweat_smile: That applies to the other rule I proposed as well. In that case, I suppose there isn't a good way for the compiler to prevent problematic usage of this feature.

I still think the feature is worthwhile though personally. To me, the problematic examples seem pretty unusual and unlikely to come up in practice. Maybe we can leverage the source compatibility suite to get a sense of how often the comma-less version of a multiline list changes semantics in practice.

As it happens something very much like this has been done already: the source compatibility suite has been run with an added step to remove commas that separate expressions that are also separated by newlines. It was run in the first place to check the resilience of the implementation, but I am running it again now with minor modifications to get a count of the number of errors that crop up from removing the comma preceding first a closure and second an implicit member expression. Once those tests have finished running, I will post the results here.

6 Likes

It's less an issue of changing semantics, and more an issue of just being potentially confusing. Before I played around with the example I posted in the thread I didn't actually know what the result would be, because I hadn't internalised all the rules around mixing whitespace and prefix/infix operators (and I doubt I'm the only one). I'm not suggesting that the inability to provide good warnings in confusing situations is fatal to the proposal, just that there is a tradeoff here and people will reasonably disagree. Personally, I haven't made my mind up. I do agree with @xwu here, though:

What is your evaluation of the proposal?
-1. I prefer to see clear difference between multiline strings and arrays/parameter lists. It could be confusing for new swift programmers.

func foo(345
               “””
                Hi
                 Ho
               “””
               Hu
               )

To me this is in spatial syntax space, so something like matrixes or vectors could benefit much more from comma-less sugar than simple arrays / comma separated lists. But I would restrict such sugar only to those more complex types.

Is the problem being addressed significant enough to warrant a change to Swift?
This is sugar and the case for it is not significant enough.

Does this proposal fit well with the feel and direction of Swift?
While simplicity and elegance are good things, they should not cause confusion, which I feel this does.

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
Not used

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
Quick reading

1 Like

Sorry, can you clarify this? What's a multiline literal that is not an array?

Sorry, meant multiline strings :flushed:

1 Like

dictionaries…

1 Like