SE-0257: Eliding commas from multiline expression lists

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.

-Chris

1 Like

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

8 Likes

@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!

-Chris

2 Likes

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.

12 Likes

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.

5 Likes

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.

5 Likes

-1

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

Could the core team address the suggested style if this were to be accepted?
For example most style guides will not suggest semicolons but only add where needed. Since this is a sugar proposal, I very much would love the direction of the core team about the suggested style for commas.

If the core team can not decide on a suggested style then that should hopefully inform the core team about their decision to accept this or not.

And I do agree about that trailing commas should be reconsidered regardless if this is accepted or not.

1 Like

To amplify this point, I observe that the guidelines for submitting a proposal say that proposals are to be submitted as pull requests in order to indicate that a review is requested. The guidelines go on to explain that a proposal will be put up for review "when the proposal is sufficiently detailed and clear, and addresses feedback from earlier discussions of the idea, the pull request will be accepted." In this case, the contemplated gate-keeping may not have been as diligent as usual. That may be a consequence of the sheer volume of proposals in recent weeks.

IMO the drafting of proposals, of late, is veering a bit much towards advocacy, and a bit away from the balanced, academic sort of presentation that has made the Swift evolution process so successful. I hope that future proposals will reverse this trend.

In no way should my comments be taken as questioning the effort or good intentions of the authors. I greatly respect and admire the contributions that @nate_chandler and @anandabits make on a daily basis, and really appreciate them and their work, overall and on this proposal.

I can't help thinking that, if this proposal were accepted, anyone who hated the elision of commas could continue to use them with very little downside — except perhaps distaste for reading code by someone else who loved the elision of commas.

I'd also suggest that characterizing this proposal as "sugar" or "cosmetic" fails to acknowledge a very well-established principle of Swift: when the compiler can infer what we mean, we are not forced to write what it can infer. This is, of course, the basis of type inference, and we're not going to abandon type inference just because the compiler can't always infer what type we mean.

There are other examples besides ; elision and type inference. Omission of the parentheses around closure parameters — { a,b in … } — is in the same category, as is the lack of function prototype declarations à la C headers. These are all things I value.

3 Likes

Maybe my arguments were not incredibly deep, but I replied twice hehe :wink:.

Actually Doug G. confirmed the issue by, paraphrasing here, taking semicolons to task and saying the issue started with allowing air elision. Look a few posts above for Doug G.’s response to Chris L. about commas elision and semicolon elision. Under that light, was semicolon elision worth that much?

Will wait for the thread to remove semicolon elision then ;).

I second this. Any reason why it's not part of the proposal?


Also it's great to see evaluations based on actual usage of the proposed feature (via a toolchain that anyone can just download and try out)! If more people did this the review threads would probably be clearer (less speculative) and the implementations would improve faster.

Perhaps the review process could benefit from including a bullet point asking about how much time was spent on actually trying out the implementation (and require that it be easily available as a toolchain)?

1 Like

This comment represents my main concern about the proposal. The inconsistency that will ensue due to ambiguities should be discussed.

3 Likes

Mild -1 from me.

I understand the desire for avoiding commas, however, this proposal seems to primarily address cases where each line starts with a parameter name. For other cases, it is likely to fail since it doesn't take indentation into consideration.

I have written on my blog about declarative syntax for building views that looks like this:

Slider(
	.isContinuous -- true,
	.minValue -- .min,
	.maxValue -- .max,
	.doubleValue <-- sliderViewState.value,
	.action(\.doubleValue) --> sliderViewState.value.update()
)

Notice that every line starts with . This is a classic example of using a variable argument list in Swift to create a mini domain-specific-language. This type of code – which would benefit more than any other from comma elision – won't work with this proposal.

I'm concerned that the failure of this proposal to work in this scenario creates the risks of increased confusion. Especially since maintaining the commas on this type of code is horrendous.

What I would like most of all is better diagnostics for this type of code since the current diagnostics in Swift are useless in these cases (literally any mistake anywhere results in a complaint about the second parameter). The only way to get useful diagnostics in this type of code is to decompose each parameter into its own statement before and you can't just comment out whole lines to find problems since if you comment out the final line, Swift won't be able to tolerate the trailing comma from the previous line (sadly, that comma proposal failed).

Unless this proposal were altered to handle lines starting with . at the same indentation level as the previous line as a new argument (rather than a continuation of the previous argument) then I think this proposal is just going to make things worse.

9 Likes

Although I do not have a definitive opinion on this proposal, I want to emphasize what I feel a lot of people have yet to realize: this feature is leaving out a large usage subset for the sake of source compatibility, and therefore becomes more complicated, inconsistent and probably brittle than it would be otherwise.

According to the document, the contents of the following array literal, as any other multiline expression list that is not a member expression but might turn out to be one, will be parsed as a single expression and unconditionally fail.

enum FooBar { case foo, bar }

let array: [FooBar] = [
  .foo
  .bar // error(fixit)
]
5 Likes

The proposal addresses this via diagnostics. In this case, a fix-it suggests a comma.

I'd like to add that I recently discovered that the proposal does not support omitting comas from parameter lists by design. I'd like to point out that even if the Core Team is convinced that the proposal is worth it, I would really urge them to consider extending it to parameter lists. It feels weird to not have it supported everywhere right now.

3 Likes