Skip to content

Commit f949743

Browse files
SE-0439: Update to address acceptance decision (#2623)
* SE-0439: Update to address acceptance decision * Update 0439-trailing-comma-lists.md * Update SE-0439 with link to previous revision --------- Co-authored-by: Xiaodi Wu <[email protected]>
1 parent e273da0 commit f949743

File tree

1 file changed

+95
-96
lines changed

1 file changed

+95
-96
lines changed

proposals/0439-trailing-comma-lists.md

Lines changed: 95 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44
* Author: [Mateus Rodrigues](https://github.com/mateusrodriguesxyz)
55
* Review Manager: [Xiaodi Wu](https://github.com/xwu)
66
* Status: **Accepted with modifications**
7-
* Implementation: https://github.com/swiftlang/swift/pull/74522# gated behind `-enable-experimental-feature TrailingComma`
7+
* Implementation: `main` https://github.com/swiftlang/swift/pull/74522#
88
* Previous Proposal: [SE-0084](0084-trailing-commas.md)
99
* Review: ([pitch](https://forums.swift.org/t/pitch-allow-trailing-comma-in-tuples-arguments-and-if-guard-while-conditions/70170)), ([review](https://forums.swift.org/t/se-0439-allow-trailing-comma-in-comma-separated-lists/72876)), ([acceptance](https://forums.swift.org/t/accepted-with-modifications-se-0439-allow-trailing-comma-in-comma-separated-lists/73216))
10+
* Previous Revision: ([1](https://github.com/swiftlang/swift-evolution/blob/7864fa20cfb3a43aa6874feedb5aedb8be02da2c/proposals/0439-trailing-comma-lists.md))
1011

1112
## Introduction
1213

13-
This proposal aims to allow the use of trailing commas, currently restricted to array and dictionary literals, in comma-separated lists whenever there are terminators that enable unambiguous parsing.
14+
This proposal aims to allow the use of trailing commas, currently restricted to array and dictionary literals, in symmetrically delimited comma-separated lists.
1415

1516
## Motivation
1617

@@ -48,7 +49,7 @@ The language has also seen the introduction of [parameter packs](https://github.
4849

4950
## Proposed solution
5051

51-
This proposal adds support for trailing commas in comma-separated lists when there's a clear terminator, which are the following:
52+
This proposal adds support for trailing commas in symmetrically delimited comma-separated lists, which are the following:
5253

5354
- Tuples and tuple patterns.
5455

@@ -66,7 +67,7 @@ This proposal adds support for trailing commas in comma-separated lists when the
6667
) = velocity
6768
```
6869

69-
- Parameter and argument lists of initializers, functions, enum associated values, expression macros, attributes, and availability specs.
70+
- Parameter and argument lists of initializers, functions, enum associated values, expression macros and attributes.
7071

7172
```swift
7273
func foo(
@@ -114,10 +115,6 @@ This proposal adds support for trailing commas in comma-separated lists when the
114115
)
115116
}
116117

117-
if #unavailable(
118-
iOS 15,
119-
watchOS 9,
120-
) { }
121118
```
122119

123120
- Subscripts, including key path subscripts.
@@ -139,164 +136,158 @@ This proposal adds support for trailing commas in comma-separated lists when the
139136
])
140137
```
141138

139+
- Closure capture lists.
140+
141+
```swift
142+
{ [
143+
capturedValue1,
144+
capturedValue2,
145+
] in
146+
}
147+
```
148+
149+
- Generic parameters.
150+
151+
```swift
152+
struct S<
153+
T1,
154+
T2,
155+
T3,
156+
> { }
157+
```
158+
159+
- String interpolation.
160+
161+
```swift
162+
let s = "\(1, 2,)"
163+
```
164+
165+
## Detailed Design
166+
167+
Trailing commas will be supported in comma-separated lists when symmetric delimiters (including `(...)`, `[...]`, and `<...>`) enable unambiguous parsing.
168+
169+
Note that the requirement for symmetric delimiters means that the following cases will not support trailing comma:
170+
142171
- `if`, `guard` and `while` condition lists.
143172

144173
```swift
145174
if
146175
condition1,
147-
condition2,
176+
condition2,
148177
{ }
149178

150179
while
151180
condition1,
152-
condition2,
181+
condition2,
153182
{ }
154183

155184
guard
156185
condition1,
157-
condition2,
186+
condition2,
158187
else { }
159188
```
189+
190+
- Enum case label lists.
191+
192+
```swift
193+
enum E {
194+
case
195+
a,
196+
b,
197+
c,
198+
}
199+
```
160200

161201
- `switch` case labels.
162202

163203
```swift
164204
switch number {
165205
case
166206
1,
167-
2,
207+
2,
168208
:
169209
...
170210
default:
171211
..
172212
}
173213
```
174-
175-
- Closure capture lists.
176-
177-
```swift
178-
{ [
179-
capturedValue1,
180-
capturedValue2,
181-
] in
182-
}
183-
```
184-
214+
185215
- Inheritance clauses.
186216

187217
```swift
188218
struct S:
189219
P1,
190220
P2,
191-
P3,
221+
P3,
192222
{ }
193223
```
194224

195-
- Generic parameters.
196-
197-
```swift
198-
struct S<
199-
T1,
200-
T2,
201-
T3,
202-
> { }
203-
```
204-
205225
- Generic `where` clauses.
206226

207227
```swift
208228
struct S<
209229
T1,
210230
T2,
211-
T3
231+
T3,
212232
> where
213233
T1: P1,
214-
T2: P2,
234+
T2: P2,
215235
{ }
216236
```
217237

218-
- String interpolation
219-
220-
```swift
221-
let s = "\(1, 2,)"
222-
```
223-
224-
## Detailed Design
225-
226-
Trailing commas will be supported in comma-separated lists whenever there is a terminator clear enough that the parser can determine the end of the list. The terminator can be the symbols like `)`, `]`, `>`, `{` and `:`, a keyword like `where` or a pattern code like the body of a `if`, `guard` and `while` statement.
227-
228-
Note that the requirement for a terminator means that the following cases will not support trailing comma:
229-
230-
Enum case label lists:
238+
Trailing commas will be allowed in single-element lists but not in zero-element lists, since the trailing comma is actually attached to the last element.
239+
Supporting a zero-element list would require supporting _leading_ commas, which isn't what this proposal is about.
231240

232241
```swift
233-
enum E {
234-
case
235-
a,
236-
b,
237-
c, // ❌ Expected identifier after comma in enum 'case' declaration
238-
}
239-
```
240-
241-
Inheritance clauses for associated types in a protocol declaration:
242-
243-
```swift
244-
protocol Foo {
245-
associatedtype T:
246-
P1,
247-
P2, // ❌ Expected type
248-
}
242+
(1,) // OK
243+
(,) expected value in tuple
249244
```
250245

251-
Generic `where` clauses for initializers and functions in a protocol declaration:
252246

253-
```swift
254-
protocol Foo {
255-
func f<T1, T2>(a: T1, b: T2) where
256-
T1: P1,
257-
T2: P2, // ❌ Expected type
258-
}
259-
```
247+
## Source compatibility
260248

261-
Trailing commas will be allowed in single-element lists but not in zero-element lists, since the trailing comma is actually attached to the last element. Supporting a zero-element list would require supporting _leading_ commas, which isn't what this proposal is about.
249+
This is a purely additive change with no source compatibility impact.
262250

263-
```swift
264-
(1,) // OK
265-
(,) // ❌ expected value in tuple
266-
```
251+
## Alternatives considered
267252

253+
### Allow trailing comma in all comma-separated lists
268254

269-
## Source compatibility
255+
Comma-separated lists that are not symmetrically delimited could also benefit from trailing comma support; for example, condition lists, in which reordering is fairly common.
256+
However, these lists currently rely on the comma after the penultimate element to determine that what comes next is the last element, and some of them present challenges if relying on opening/closing delimiters instead.
270257

271-
Although this change won't impact existing valid code it will change how some invalid code is parsed. Consider the following:
258+
At first sight, `{` may seem a reasonable closing delimiter for `if` and `while` condition lists, but conditions can have a `{` themselves.
272259

273260
```swift
274261
if
275-
condition1,
276-
condition2,
277-
{ // ❌ Function produces expected type 'Bool'; did you mean to call it with '()'?
278-
return true
279-
}
280-
281-
{ print("something") }
262+
condition1,
263+
condition2,
264+
{ true }(),
265+
{ }
282266
```
283267

284-
Currently the parser uses the last comma to determine that whatever follows is the last condition, so `{ return true }` is a condition and `{ print("something") }` is the `if` body.
268+
This particular case can be handled but, given how complex conditions can be, it's hard to conclude that there's absolutely no corner case where ambiguity can arise in currently valid code.
285269

286-
With trailing comma support, the parser will terminate the condition list before the first block that is a valid `if` body, so `{ return true }` will be parsed as the `if` body and `{ print("something") }` will be parsed as an unused closure expression.
270+
Inheritance lists and generic `where` clauses can appear in protocol definitons where there's no clear delimiter, making it harder to disambiguate where the list ends.
287271

288272
```swift
289-
if
290-
condition1,
291-
condition2,
292-
{
293-
return true
273+
protocol Foo {
274+
associatedtype T:
275+
P1,
276+
P2, ❌ Expected type
277+
...
294278
}
279+
```
295280

296-
{ print("something") } // ❌ Closure expression is unused
281+
```swift
282+
protocol Foo {
283+
associatedtype T:
284+
P1,
285+
P2, ❌ Expected type
286+
...
287+
}
297288
```
298289

299-
## Alternatives considered
290+
Although some comma-separated lists without symmetric delimiters may have a clear terminator in some cases, this proposal restricts trailing comma support to symmetrically delimited ones where it's clear that the presence of a trailing comma will not cause parsing ambiguity.
300291

301292
### Eliding commas
302293

@@ -312,3 +303,11 @@ print(
312303
This was even [proposed](https://forums.swift.org/t/se-0257-eliding-commas-from-multiline-expression-lists/22889/188) and returned for revision back in 2019.
313304

314305
The two approaches are not mutually exclusive. There remain unresolved questions about how the language can accommodate elided commas, and adopting this proposal does not prevent that approach from being considered in the future.
306+
307+
## Revision History
308+
309+
- Update to address acceptance decision of restricting trailing comma to lists with symmetric delimiters.
310+
311+
## Acknowledgments
312+
313+
Thanks to Alex Hoppen, Xiaodi Wu and others for their help on the proposal text and implementation.

0 commit comments

Comments
 (0)