SE-0257: Eliding commas from multiline expression lists

(Suyash Srijan) #90

This. +1

(Jarod Long) #91

I don't think this is totally fair — I disagree that two syntactic refinement proposals constitutes a wide range. Bigger fish are in fact still being fried, and I see no reason that we shouldn't make a small amount of room for small refinements like this. There will always be bigger problems to address than syntax refinement, but by that logic there will never be a time to address these issues.

(Douglas Gregor) #92

The same "special case" already exists for semicolon elision in statements.

This analogy does not fit at all. The closest analogy is eliding semicolons between statements; it is literally the same feature.

It's a separate value, just like if you wrote

(6 * 9)

in today's Swift.

There is literally nothing new in that section: these are the rules of Swift's grammar today for semicolon elision with statements. There is a practical difference in that you're more likely to bump into these cases in an expression list (comma elision) than in a statement list (semicolon elision).

This does not follow at all from the proposal. The proposal applies precisely the same logic used for semicolon elision of statements to comma elision of expression lists; it does not otherwise expand the rules.

For reference, I posted an extensive reply to your critique within the pitch thread, to which you did not reply.

(I'll separately post my own thoughts on this part, which are quite subjective)

As I noted in my reply on the pitch thread, this is incorrect. Specifically, I wrote:

Also as I noted in the pitch thread, this is incorrect. Specifically, I wrote:

(skipping the more-subjection comment, so...)

To which I replied in the pitch thread:

Our 8+ years of semicolon elision have prepared the language and tools for this change. So while it is a significant stylistic change to the language, it is not a radical technical change.


(Douglas Gregor) #93

Semicolon elision in statements isn't quite so perfect as you make it sound---we have newline-sensitive rules around the opening parenthesis for call expressions that would surprise people if laid out in detail like this proposal's "exceptions" section, for example---and whitespace sensitivities around operators that can be a surprise. As I noted elsewhere, the exceptions will occur somewhat more often because of leading dot syntax, but it's far from the radical departure you describe.


(Preston Sumner) #94

I'd add that sugar is a common topic dating back to the old mailing list, and in fact, the two examples given have a history of older related threads. I don't think that means the ball is being dropped in other areas. Point taken that this is low priority, but I think everyone acknowledges that. That said, when it comes to using Swift for configuration or other problems involving lists, which motivates my interest in this change, I don't think this is as superficial a thing to give some thought to as suggested.

(Douglas Gregor) #95

Indeed. Of the recent proposals that we reviewed, two are syntactic tweaks (this and SE-0255), two are providing more-strongly-typed counterparts to existing dynamic features (SE-0252 and SE-0253), two improve numerics support (SE-0251 and SE-0246), and several others make substantive expressibility improvements (SE-0244, SE-0249). Combine that with active movement on property delegates, custom attributes, explicit member wise initializers and variadic generics, I'd say we have a healthy mix of proposals moving through the pipeline.


(Douglas Gregor) #96

+1. This eliminates unnecessary noise in Swift code, giving it a lighter feel and eliminating a minor day-to-day nuisance with trailing commas. It makes simple things like reordering elements in a large array/dictionary literal easier. And much like with semicolons, once they're gone I realize that I simple don't miss them---because they weren't adding anything to my code

It's a syntactic refinement, but it's one that makes a lot of code just a little less noisy, and the cumulative effect is quite strongly positive. After looking at the examples for a while, the extraneous commas begin to feel very heavy.

In-depth study, including participation in the pitch thread and review of the implementation.


(Ben Cohen) #97

I'm an enthusiastic supporter of this change.

I was pretty disappointed to see SE-0084 rejected back in the day. I have often found the lack of trailing commas on expressions frustrating given the circumstances that make them useful for arrays apply to other expression lists too.

The rejection rationale also didn't ring true:

For parameter lists and tuples (the specific topic of the proposal), the trailing terminator of the list is typically placed on the same line as the other elements.

The standard library actually follows a formatting convention (subsequently also adopted by Google's style guide) that absolutely can end up with parameter lists with their trailing terminator on the subsequent line, so all the same good arguments in favor of trailing commas in arrays (like reducing diff noise) also apply. I raise this because a lot of the discussion has been focused on DSLs, but this is an example of it impacting regular code.

So I had for a while been hoping that the subject of SE-84 might get revisited. It had never occurred to me that eliding commas, just like eliding semi-colons, was a far more elegant solution. The subsequent pitch discussion has reinforced this, to the point where, like @nnnnnnnn points out, some of the commas I see are now really bugging me! Thinking about how the standard library would look without them makes me confident this would be a positive change for the language.

I understand that some might feel we've gone beyond that point in the evolution of the language. I really hope not. This kind of change – the adoption of which is entirely discretionary and can be done at the pace of the adopter's choosing – seems like the perfect way to evolve the language and continue to make it better for many new use cases.

(Matthew Johnson) #98

I couldn’t agree more. The recent period has been the most active in a long time for SE. This is very exciting! One of the most exciting things about it for me has been seeing new community compiler implementers making contributions. I think it is perfectly reasonable for new implementer to choose to start with relatively small features, which will often be some kind of syntactic sugar. It would be quite unreasonable to expect such contributors to start with large features that impact every corner of the language, change the type system, etc. These contributions are not holding up work on larger features. They represent additional work that would not otherwise happen (at least not right now).

For this reason, I find the tone in some of the comments in the threads about this topic rather troubling. There have been a few that are rather condescending with a rather strongly negative vibe. IMO, this is disrespectful towards the time and effort @nate_chandler has invested in getting up to speed on the compiler and making contributions to the community. We can and should be able to disagree without being disrespectful or condescending. In fact, the code of conduct requires this of all of us. I hope the remainder of this review thread will take on a more respectful tone, even where people strongly disagree with this proposed direction.

(Paul Cantrell) #99

After spending some time with the toolchain, I rather like it.

I’m a comfortable but not vehement +1 on this, with one caveat about function declarations.

  • What is your evaluation of the proposal?

I came to it with mixed feelings.

On the one hand, I am an enthusiastic proponent of removing syntactic noise. I used to sneer at syntactic gymnastics to reduce delimeters, but actually working with languages that did such gymnastics convinced me of the readability benefit. It’s simply easier to see the code if there’s less visual distraction in it. I’ve come to believe that Edward Tufte’s “data-to-ink ratio” applies to code as much as any other form of information design.

On the other hand, this seemed like such a fiddly little change that it’s hardly worth the syntactic confusion I assumed it would create. And I assumed there would be lots — as there is with Javascript’s vexingly almost-but-not-quite-optional semicolons.

After spending some time with the toolchain, I didn’t find any Javascript-like bizarre corner cases, even with my bizarre taste in formatting. (Whitesmiths! don’t @ me) This proposal really does slip into the language with shocking ease, just as its authors suggest!

The result is often nothing more than a subtle and pleasant shift:

return RequestTransferMetrics(
    requestBytesSent:      task.countOfBytesSent
    requestBytesTotal:     task.countOfBytesExpectedToSend
    responseBytesReceived: task.countOfBytesReceived
    responseBytesTotal:    task.countOfBytesExpectedToReceive)

…but in some cases opens up striking possibilities, as in this fussy little helper method that sans commas becomes reminiscent of Smalltalk’s conditionals:

    ifObserver: {
        observerIsOwner = false
    else: {

Here a print statement benefits from breaking a long string across lines:

    "WARNING: Received response for request that was already completed:"
    "This may indicate a bug in your NetworkingProvider, your custom"
    "RequestDelegate, or Siesta itself. If it is the latter, please"
    "file a bug:"
    "\n    Previously received:", existingResponse
    "\n    New response:", newResponse)

The real clincher for me is what the proposal does to SwiftPM package config:

let package = Package(
    name: "Paper"
    products: [
        .executable(name: "tool", targets: ["tool"])
        .library(name: "Paper", targets: ["Paper"])
    dependencies: [
        .package(url: "", from: "1.2.3")
        .package(url: "../CHTTPParser", .upToNextMinor(from: "2.2.0"))
        .package(url: "http://some/other/lib", .exact("1.2.3"))
    targets: [
            name: "tool"
            dependencies: [
            name: "Paper"
            dependencies: [
                .target(name: "Utility")
                .product(name: "CHTTPParser")

That’s nice. The raggedy commas in Package.swift always bother me!

The one snag I hit is that the proposal does not support comma elision in function signatures:

public func request(
        _ method:        RequestMethod   // compiler error here
        data:            Data
        contentType:     String
        requestMutation: @escaping RequestMutation = { _ in })
    -> Request

The language really ought to support comma elision in the declaration, since it supports it in the corresponding call. It will certainly cause frustration otherwise.

  • Is the problem being addressed significant enough to warrant a change to Swift?

This is certainly debatable (as the debate here shows).

Opening up the possibilities of more fluid and readable Swift DSLs seems to me to be worth the fuss, but I don’t have vehement feelings about this.

  • Does this proposal fit well with the feel and direction of Swift?

To the extent that Swift goes out of its way to reduce visual noise (optional semicolons, type inference, .-prefix use of the contextual type as an implicit namespace, trailing closures, anonymous closure args, type sugar for arrays and dicts), I’d say yes, it does fit with the feel of Swift.

To the extent that Swift is a C descendant, it feels odd. However, Swift is syntactically already a long way from C; see previous paragraph.

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

My time with Ruby, Python, Smalltalk, and Elm — all relatively low-delimeter languages — has made me appreciate the value of reduced visual noise in code.

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

I only skimmed the proposal, but spent some quality time with the toolchain.

(Douglas Gregor) #100

This is a great way to experience a proposed new feature, especially one that has a stylistic impact like this proposal. Cool!


(Paul Cantrell) #101

Ben’s sentiment here resonates with me. Swift is a pleasure more often than not, but still doesn’t feel fully mature. Despite the push for stability of user experience in recent versions of Swift, I’d like to think it still has room to grow.

Whether this proposal is accepted, I hope that we will keep shaving away the language’s burrs and rough spots, with an eye not just to completeness (huzzah for the recent generics push!) but also to lowering user friction.

1 Like
(Chris Lattner) #102

I'm exceedingly aware of the rules around whitespace, the special cases we built to make semicolon elision work in practice, as well as the sharp edges. Are you claiming that there is a widespread use of necessary semicolons outside of intraline separators? Please provide some examples (i.e., links to github projects).

The proposal gives several examples of where comma separation will be necessary in common cases and prominent members of the community have already pointed out that this proposal is a fail for core infra of the Swift project like SwiftPM, so I have a hard time understanding your position here.


1 Like
(Chris Lattner) #103

I'm sorry for the delay and interruption responding to this thread. As the core team was aware when they scheduled and ran this, I was traveling and have not had time nor internet connectivity to participate in a very engaged way.

As I pointed out with a detailed comment, this is not the case despite repeated claims about it. Semi colon elision allows effectively 100% elimination of semicolons which make end of line separators effectively "not exist". This proposal eliminates some large but non-total number of commas (80%, 90%, has anyone actually measured?) which leads to the language being inconsistent, and feel unpredictable to users. These are completely different things. Unless the proposal effectively eliminates commas as line separators, it is not at all in the same ballpark.

No, it is not. Again, the point is this is not at all consistent like semicolon elision is, and I have a hard time understanding how you would continue to claim this when the proposal itself explicitly acknowledges this. This is a special case that makes some demos look less punctuated, but when prominent members of the community are saying things like:

I have never looked at code and thought "you know what this needs? fewer commas".

Then perhaps there is no problem that needs to be solved here.

I apologize for not responding. As I mentioned before, I have been traveling, which you knew.
The standard expectations of the community for pitch thread is that the community does not need to follow the entire thread - the expectations are that the feedback from the pitch threads are incorporated into the proposal which was not done in this case.

Agreed, you are correct, there is no backwards compatibility issue here.

Correct, but those cases (by design!) don't happen in a statement scope because they don't produce a side effect. No-op values at statement scope aren't something people try to write, and if they did, they wouldn't be something you'd make explicitly "work" by adding semicolons. Swift was designed for this specific case, and claiming that the same logic generalizes to commas is missing the core design of the expression grammar.

This is ignoring the indentation rules that make that case "do the right thing" in practice for statements which does not generalize to commas. However, I'll ignore that for the moment to dive into the deeper issue:

Let me rephase your argument: you are saying that this proposal is going to regress the user experience of using swift so badly that you'll be forced to do QoI improvements that could have been done at any point, but which never mattered enough to justify the engineering effort. You appear to be claiming that this is a net positive for the Swift language, community, and long term evolution of the language. I will simply state that this logic doesn't make sense to me.

Among other things, I would love to see the data you have that shows this is the only user experience regression that people will hit in practice, I would also love to see the code bases that you've converted over, and the indication of how successful comma elision will be in practice (90%? 99.9%?) and therefore how inconsistent we can expect Swift code to be in the future in practice if this proposal is accepted.

This proposal is a huge change to the user-visible feel of the Swift language. Such a change, particularly given the low benefit demands overwhelming evidence that this will be a positive move for the language and community. I simply cannot believe how fast you are apparently pushing for this to happen. Even if this did make the Swift language better, doing this with the proper data, justification and experience would be absolutely expected of any other sugar proposal - I don't see why such an invasive change could be done with less diligence.


(Chris Lattner) #104

@nate_chandler, I just want to say, for the record, that I appreciate your work and contributions to the community. Please do not take any of my concerns about the technical direction of the language as a reflection on your work or intent. I consider it a critical priority that we make deliberate and careful steps in the evolution of the Swift language.

In any case, I'm very glad that you've joined Apple DevTools and that this allows you to invest more time into the Swift community and in swift-evolution proposals. Thank you for your work!



In a bid to show how much subjectivity is part of this debate, I find this example extremely jarring. My eyes keep looking for the commas, even though I know the entire point is to show how nice it looks without them. It just feels off to me at an almost instinctual level.

I know I would never be forced to write code like that, but I'd have a hard time reading others' code if comma-elision became pervasive.

1 Like

See, now I look at this and all I can see are the two commas that are still there and find myself wondering "Why are they there?" "Why isn't there one preceding delegate.requestDescription?" "Is there something special about those two items?" "What information is being conveyed by those two commas?"

Now, in the middle of this discussion, I know why the commas are there. But if I were to see it in the wild I would be unnecessarily distracted trying to figure out the purpose of those commas before realizing that it was simply that they were on the same line as the preceding string and that horizontal whitespace isn't as special as vertical whitespace. I should also note that I don't think this is ameliorated if delegate.requestDescription is spliced onto the end of the first line with a comma.

In a case like this, the partial elision of commas makes things worse, not better.

(Paul Cantrell) #107

Yeah, familiarity bias reigns supreme in our reactions to programming languages. This is why gut reactions are not particularly useful when looking at new language features: human brains react first to how familiar something appears, and only later to the thing itself.

I do recommend taking the time to download the toolchain and give your brain a chance to get used to this proposed feature.

(Preston Sumner) #108

Subjectivity colors my position as well. Having worked with Squirrel, which is used to script the Source engine, I'm comfortable with table constructors that look like this:

DirectorOptions <- {
    PreferredMobDirection = SPAWN_LARGE_VOLUME
    PreferredSpecialDirection = SPAWN_LARGE_VOLUME
    ShouldConstrainLargeVolumeSpawn = false
    MobSpawnMinTime = 45
    MobSpawnMaxTime = 90
    CommonLimit = 15
    ZombieSpawnRange = 3000

I'm used to it, so I can't help but disagree that there's no increase in readability. With comma elision, I imagine using Swift for game configuration and feeling comfortable opening it up to designers or other non-programmers to adjust. Would commas really prevent my doing so? Maybe not, but I prefer this formatting because of my experience with it.

(Joe Spadafora) #109


The only part that resonates with me is when I need to juggle a comma when rearranging a list. I would much prefer to allow trailing commas in collection lists and other places to the proposed change. I don't feel a comma at a separator is that onerous of a request.

I've followed both this thread and the pitch and read them fully.

1 Like