Skip to content

Commit eae494c

Browse files
authored
Merge pull request #533 from dwijnand/sip-trailing-commas
SIP-27 Trailing Commas
2 parents b3ee5b3 + b2ab043 commit eae494c

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
---
2+
layout: sip
3+
disqus: true
4+
title: SIP-27 - Trailing Commas
5+
---
6+
7+
# SIP-27: Trailing Commas
8+
9+
**By: Dale Wijnand**
10+
11+
## History
12+
13+
| Date | Version |
14+
| ---------------|-------------------------------------------------|
15+
| Jun 25th 2016 | Initial Draft |
16+
| Jun 27th 2016 | Added drawback of changing existing tools |
17+
| Jun 27th 2016 | Added motivation that it simplifies codegen |
18+
| Jun 28th 2016 | Fixed a typo |
19+
| Aug 10th 2016 | Renamed from SIP-NN to SIP-27 |
20+
| Aug 10th 2016 | Changed scala-commas URL (repo was moved) |
21+
| Aug 10th 2016 | Dialed back some of the language from review |
22+
| Sep 04th 2016 | Split the motivation into sections |
23+
| Sep 04th 2016 | Add VCS authorship attribution to motivation |
24+
| Sep 04th 2016 | Add Cross building hinderance to drawbacks |
25+
| Sep 12th 2016 | Remove Cross building hinderance from drawbacks |
26+
27+
## Motivation
28+
29+
### Easy to modify lists
30+
31+
When using a comma-separated sequence of elements on multiple lines, such as:
32+
33+
{% highlight scala %}
34+
Seq(
35+
foo,
36+
bar,
37+
baz
38+
)
39+
{% endhighlight %}
40+
41+
It is quite inconvenient to remove or comment out any element because one has to think about the fact that the last element mustn't have a trailing comma:
42+
43+
{% highlight scala %}
44+
Map(
45+
foo,
46+
bar //,
47+
// baz
48+
)
49+
{% endhighlight %}
50+
51+
Secondly, it is quite inconvenient to re-order the sequence, for instance if you wanted `baz` before `bar` you need to micromanage which is followed by a comma and which isn't:
52+
53+
{% highlight scala %}
54+
val xs = Seq(
55+
foo,
56+
baz // This isn't going to work
57+
bar,
58+
)
59+
{% endhighlight %}
60+
61+
### Reduce diff noise
62+
63+
Allowing trailing commas also reduces a lot of noise in diffs, such as:
64+
65+
{% highlight diff %}
66+
@@ -4,7 +4,8 @@
67+
Map(
68+
foo,
69+
bar,
70+
- baz
71+
+ baz,
72+
+ quux
73+
)
74+
{% endhighlight %}
75+
76+
### VCS authorship attribution
77+
78+
Using the example above, the authorship of the `baz` line would be preserved, instead of becoming that of the author of the `quux` line.
79+
80+
### Simplify code generation
81+
82+
Such a feature would also simplify generating Scala source code.
83+
84+
### Long standing ticket
85+
86+
There is an open ticket ([SI-4986][]) where this feature was requested, referencing the fact that it facilitates code generation by tools and allows for easier sorting of the values, initially in the context of import selectors but later also for other constructs in the syntax.
87+
88+
### Real-world use-cases
89+
90+
Some real-world use-cases where elements of a sequence are typically added, removed or moved are:
91+
92+
* invoking constructors or methods (such as `apply` or `copy`) which present a lot of options defined with default values
93+
* `settings(...)` arguments or elements of `libraryDependencies`, `scalacOptions` or `javaOptions` sequences in sbt
94+
95+
## Design Decisions
96+
97+
There are a number of different elements of the Scala syntax that are comma separated, but instead of changing them all a subset of the more useful ones was chosen:
98+
99+
* tuples
100+
* argument and parameter groups, including for implicits, for functions, methods and constructors
101+
* import selectors
102+
103+
From the spec these are:
104+
105+
* SimpleExpr1, ArgumentExprs via Exprs
106+
* ParamClause, ParamClauses via Params
107+
* ClassParamClause, ClassParamClauses via ClassParams
108+
* ImportSelector
109+
110+
The elements that have not changed are:
111+
112+
* ValDcl, VarDcl, VarDef via ids
113+
* Type via FunctionArgTypes
114+
* SimpleType, TypeArgs via Types
115+
* Expr, ResultExpr via Bindings
116+
* SimplePattern via Patterns
117+
* TypeParamClause, FunTypeParamClause
118+
* ImportExp
119+
* PatDef
120+
121+
## Implementation
122+
123+
The implementation is a simple change to the parser, allowing for a trailing comma, for the groups detailed above, and has been proposed in [scala/scala#5245][].
124+
125+
## Drawbacks/Trade-offs
126+
127+
The drawback, or trade-off, to this change is that it adds another way in which it is possible to do something in Scala. But it is the opinion of this SIP that the pragmatic advantage of being able to have trailing commas is worth this drawback.
128+
129+
Given that this is a change in syntax, another drawback is that it requires changing the existing tools, such as those that parse Scala: intellij-scala, scalariform, scala.meta and scalaparse.
130+
131+
## Alternatives
132+
133+
As an alternative, trailing commas support could be added universally to all the comma-separated elements of the syntax. This would mean changing more (but still only in the parser), but it would make it consistent.
134+
135+
As an alternative to changing the language, there already exists today a compiler plugin called [scala-commas][] that provides this feature. It also provides some evidence that people would even use unsupported compiler apis and reflection to add this functionality, even when such a plugin won't compose with other plugins well, though arguably only weak evidence as it's a young and obscure plugin.
136+
137+
## References
138+
139+
1. [SI-4986][]
140+
2. [scala/scala#5245][]
141+
3. [scala-commas][]
142+
143+
[SI-4986]: https://issues.scala-lang.org/browse/SI-4986
144+
[scala/scala#5245]: https://github.com/scala/scala/pull/524://github.com/scala/scala/pull/5245
145+
[scala-commas]: https://github.com/47deg/scala-commas

0 commit comments

Comments
 (0)