Skip to content

SIP-27 Trailing Commas #533

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Sep 23, 2016
Merged
121 changes: 121 additions & 0 deletions sips/pending/_posts/2016-06-25-trailing-commas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
layout: sip
disqus: true
title: SIP-NN - Trailing Commas
---

# SIP-NN: Trailing Commas

**By: Dale Wijnand**

## History

| Date | Version |
|---------------|---------------|
| Jun 25th 2016 | Initial Draft |

## Motivation

When using a comma-separated sequence of elements on multiple lines, such as:

{% highlight scala %}
Seq(
foo,
bar,
baz
)
{% endhighlight %}

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:

{% highlight scala %}
Map(
foo,
bar //,
// baz
)
{% endhighlight %}

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:

{% highlight scala %}
val xs = Seq(
foo,
baz // This isn't going to work
bar,
)
{% endhighlight %}

Additionally, this means that there is a lot of noise in diffs, such as:

{% highlight diff %}
@@ -4,7 +4,8 @@
Map(
foo,
bar,
- baz
+ baz,
+ quux
)
{% endhighlight %}

Also such feature would massively simplify generating Scala source code.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/massively/modestly/ IMO — "massively" just seems like hyperbole. or is it really that big an issue in your experience? (I do have some experience writing code generators that omitted trailing commas and found it annoying, but really not that a big deal, either.)


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.

Some real-world use-cases where elements of a sequence are typically added, removed or moved are:

* invoking constructors or methods (such as `apply` or `copy`) which present a lot of options defined with default values
* `settings(...)` arguments or elements of `libraryDependencies`, `scalacOptions` or `javaOptions` sequences in sbt

## Design Decisions

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:

* tuples
* argument and parameter groups, including for implicits, for functions, methods and constructors
* import selectors

From the spec these are:

* SimpleExpr1, ArgumentExprs via Exprs
* ParamClause, ParamClauses via Params
* ClassParamClause, ClassParamClauses via ClassParams
* ImportSelector

The elements that have not changed are:

* ValDcl, VarDcl, VarDef via ids
* Type via FunctionArgTypes
* SimpleType, TypeArgs via Types
* Expr, ResultExpr via Bindings
* SimplePattern via Patterns
* TypeParamClause, FunTypeParamClause
* ImportExp
* PatDef

## Implementation

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][].

## Drawbacks/Trade-offs

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.

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.

## Alternatives

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.

As an alternative to changing the language, there already exists today a compiler plugin called [scala-commas][] that provides this feature. It also provides 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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, only very weak evidence — it's an obscure plugin, described by its author as "a proof of concept, for fun". it does have 27 stars on GitHub, but it also has no issues, no PRs, and only a handful of commits.


## References

1. [SI-4986][]
2. [scala/scala#5245][]
3. [scala-commas][]

[SI-4986]: https://issues.scala-lang.org/browse/SI-4986
[scala/scala#5245]: https://github.com/scala/scala/pull/524://github.com/scala/scala/pull/5245
[scala-commas]: https://github.com/andyscott/scala-commas
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is https://github.com/47deg/scala-commas a better URL for this? it has 27 stars, the andyscott one only has 1 star.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's a quick reaction. I think the proposal goes too far in that it allows trailing commas in lots of contexts which IMO do not make sense.

I propose we go slowly and only accept trailing commas for tuples right now and we include Tuple1. Anything else might risk overshooting.

The danger I see is that there is a good prospect that trailing commas will have a semantic meaning connected with Hlists. But if we go overboard now and accept them everywhere we give up the opportunity to establish a nice correspondence between syntax and semantics.

We can come back to the issue of generalizing trailing commas once Hlists are implemented. But Hlists should come first, as they are the truly important part.

Martin

Sent from my iPhone

On 10.08.2016, at 09:16, Seth Tisue [email protected] wrote:

In sips/pending/_posts/2016-06-25-trailing-commas.md:

+## Alternatives
+
+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.
+
+As an alternative to changing the language, there already exists today a compiler plugin called [scala-commas][] that provides this feature. It also provides 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.
+
+## References
+
+1. [SI-4986][]
+2. [scala/scala#5245][]
+3. [scala-commas][]
+
+[SI-4986]: https://issues.scala-lang.org/browse/SI-4986
+[scala/scala#5245]: scala/scala#524
+[scala-commas]: https://github.com/andyscott/scala-commas
is https://github.com/47deg/scala-commas a better URL for this? it has 27 stars, the andyscott one only has 1 star.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would be the point of trailing commas in tuples? Trailing commas are useful for reordering or removing elements. Tuples are fixed arity and heterogeneously typed. If there aren't going to be trailing commas for argument lists, you're better off doing nothing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to parameter and argument lists being the most important use case to cover. Everything else less important.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there aren't going to be trailing commas for argument lists, you're better off doing nothing

Yeah, I said nearly exactly that during the SIP meeting.