Yes, in a sense, that is my point. The proposal shouldn't include only examples of usage that people would be more likely to use, but should give examples of the full picture of what will be allowed.
This allows reviewers a fair comparison to consider the tradeoff between the readability of use on multiple lines, and introducing the potential for, as you say, the very unpleasant reading on a single line.
Very strong +1, this has been a long-standing issue and quite a frustrating inconsistency in the language.
Yes, absolutely. I stumble upon this consistency daily when reordering function/initializer arguments during refactoring.
Yes, I have no doubt in that. It would follow the principle of least surprise and make the language more consistent.
Yes, I believe so. I don't remember all of the languages that have it off the top of my head, but Swift always felt the odd one out in its inconsistency of trailing commas parsing.
I read the whole proposal and followed previous pitch threads.
huge +1, especially for function parameters, this is a constant paper-cut to have to manually add/remove commas when adding/removing/re-ordering params.
+1. Ugly on single lines but thatâs not what itâs for. Having to manually add or remove commas is a small but not infrequent source of frustration. Good experience with Rustâs equivalent.
Aside: Right now, swift-format always removes the trailing comma from single-element lists. This limitation (result of a bug fix IIRC) is a small annoyance now but definitely needs to be addressed if the proposal is accepted.
I don't see why it "definitely needs" to be addressed, aside from the fact that it will make slightly noisier diffs when new elements are added to the array. But that's no different than the case today.
Slight aside: The reason swift-format has that behavior is to avoid the awkward case where an array literal is actually an array type written in an expression context. We want to avoid this:
let x = [
SomeReallyLongTypeName,
]()
The compiler actually allows this! But it's inconsistent with the syntax for arrays in type context:
let x: [
SomeReallyLongTypeName, // syntax error!
] = [...]
And this proposal would not change that, because ArrayTypeSyntax does not have a comma at all (nor should it).
So back to the array literal case, without semantic information, there's no 100% reliable way to distinguish one-element array literals that are true literals from array literals that are expressing the type.
As this proposal relates to formatting, I think it would be straightforward to extend swift-format's current handling of trailing commas in array literals (but without the one-element exception) to enforce trailing commas at the ends of lines anywhere that the proposal supports it, and to remove them otherwise. For example, if the trailing comma behavior were enabled:
someFunction(
x,
y // running swift-format would add a comma here
)
someFunction(x, y,) // running swift-format would remove the trailing comma
Since the idea of the proposal is to reduce noisy diffs and comma churn, my point is that it would be unfortunate if swift-formatreintroduces some of that. Could this be addressed on the language side?
That's fair. I think an argument could be made that it would be extra weird to accept let x: [T,] since in that position it's not serving as a list of any sort, and it's not a hard exception for swift-format to work around because there's no trailingComma token slot in the AST anyway. But aside from that, I honestly don't have a super strong opinion about it. It would have the advantage of making things more consistent.
(And for posterity's sake, everything I've said about array literals here also applies to dictionary literals.)
My point is that it wouldn't be re- introducing anything. The special case for one-element collections already exists and if left alone, would continue to exist, but it wouldn't expand to other one-element syntactic lists. Hence my questioning of "definitely needs" to be addressed. I think it's just a "would be nice to" address.
I concede that my phrasing was a bit unfortunate. âReintroduce churnâ for users who adopt swift-format, now that it ships with Xcode etc. Not against the letter but the spirit of SE-0439. It would be nice to address this.
I disagree with your contention that it only makes code less readable. There are certain cases - such as macros - that would become more readable if developers didn't have to include code for a special condition for the last element when generating comma separated lists.
I didn't realise it until @mergesort penned it this way, but apparently I too have been using roughly this mental model. And it makes a lot of sense, now that I think about it consciously rather than instinctively.
I want to stress that just because you can change e.g. the parameters of a function, that doesn't mean it's typical nor expected. I expect that most functions never change their parameters (and any which change a lot maybe hint at something wrong, like poor design or failure to use variadics appropriately).
@maartenecommented on this too, but I'll emphasise his point that allowing commas in places where there cannot be any more elements is really weird. It's conceptually wrong, and while I'm sympathetic to the pragmatist position, it feels like something newcomers will be forever befuddled by. I'm not sure "because common diffing programs at the time couldn't handle it" is going to age well as an explanation for the proposed syntax change.
Variadic functions are an interesting case, though. I still find the superfluous trailing comma to be undesirable overall - especially since variadicity is sometimes an implementation detail, that the caller should not have to care about - but I can see there's a stronger argument to be made for it there.
I'd like to highlight that one of the arguments used in favour of this proposal - "it may not be totally consistent but it works in most places and it's worth it" - was also used for the eliding commas proposal and was largely rejected there.
Especially since those two proposals are competitors (in the sense of both trying to address essentially the same problem), it would be rather strange to not apply consistent logic.
Relatedly, when two approaches are competing to solve a problem, it seems only sensible to give preference to one which removes syntax rather than adding it. See also formative decisions around semicolons, ++ / --, C-style for(;;) loops, etc.
The proposal asserts - and is substantially predicated on the premise - that putting closing parenthesis on their own line is increasingly common if not the common style in Swift. That's news to me. I certainly do see code formatted that way occasionally, but it's unusual and stands out (I usually assume it's just someone coming from another language and bringing habits with them).
The "you can just ignore the spurious commas" argument is essentially the same as "you can just ignore the diff noise". I guess they cancel each other out, as matters of persuasion? They're just expressing purely subjective preferences as to which is the more or less annoying place to have noise, and I don't see anything like a plurality let-alone a consensus on that answer.
It's also unclear if there's any kind of objective preference to be had, as in past discussions of this pitch there's been assertions & anecdotes going both ways as to whether this will make it easier or harder for tools to that read / modify / write Swift code.
I'm not sure what you mean by "cannot". It seems to me that just about all the cases we're talking about (everything except function parameters?) don't have a fixed number of elements. You could always add another guard condition or protocol conformance.
Is the problem being addressed significant enough to warrant a change to Swift?
This is considered a "quality of life improvement", that also suggests that other "comma-separated lists in the language could also benefit from the flexibility enabled by trailing commas", but that argument has not been made nor enough evidence been shown to convince me.
The specific text in the proposal that gives me pause is (emphasis mine):
This proposal adds support for trailing commas in comma-separated lists when there's a clear terminator, which are the following:
Are we expected to think like a Language Parser to use this feature correctly? A semicolon is a clear terminator, but I didn't see that mentioned in the proposal. But based on that exact language used as the proposed solution, I would half expect this to work:
enum E {
case
a,
b,
c,; â Ok, uses a clear terminator
}
Does this proposal fit well with the feel and direction of Swift?
Perhaps
If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
This is a new one for me.
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
I read the proposal and most of the forums comments.
It's a matter of degree. It's more likely that one will add or remove items from a list than from a function call than from a guard statement, etc.
As @maartene noted, a list is conceptually variable - and at runtime it's literally a mutable type. Whereas most of the other situations are much less so.
(this would be even clearer if Swift's tuples were first-class collections like in e.g. Python - currently they're a bit overloaded when it comes to mutability vs immutability)
Put another way, a trailing comma to me says "and [then]" (since that's literally its meaning in English) which is not usually the actual, current intent when writing conditional statements, function calls, etc. Just because the latter can change doesn't mean it's expected (or intended, or desired, etc).
The lack of support for trailing commas in enums is another way in which this intuition is violated, since of all the examples it's one of the most logical to support trailing commas, yet per the proposal it will not.
I am reluctantly +1. This allowance will put this in alignment with what was already accepted (array and dictionary literals), and it solves a very small âproblemâ that even I get annoyed with (quickly copy and pasting lines in these literals and now arguments/parameters).
It is restricted to those areas. So I approve.
I would hope it would not be allowed in cases such as foo(x,y,z,) as this is very ugly. I understand why that wouldnât be disallowed.
If it werenât for it already being allowed in collection literals, I wouldnât have added it to the language.
Any rationale for not allowing this would apply equally to collections, where it's already allowed. As far as I'm concerned that makes such objections moot.
If you don't like this style, that's completely understandable, but that's why we have formatters/linters.
Not exactly. That something is partially permitted doesn't logically means it should be fully permitted.
It does put empirical limits on some potential arguments (e.g. the sky will fall if we add this!), but not much more. Every proposal should have its own merits, not merely be based on partial precedent (it's not even a case of saying "it'll be more consistent" because in this case you can go either way to improve consistency - and indeed, if consistency is your goal then it appears the only viable way is to remove support for trailing commas in all cases).