Greetings, Scala users and contributors!
This thread is the SIP (Scala Improvement Process) Committee’s request for comments on a proposal to deprecate and eventually remove symbol literals from the language.
The discussion will remain open until the committee’s April meeting (likely around April 16th).
We propose to deprecate, then later remove, the single-quote
'foo syntax for
constructing instances of
For more than a decade, the Scala standard library has included a
scala.Symbol class. As the Scaladoc for Symbol states,
This class provides a simple way to get unique objects for equal strings. Since symbols are interned, they can be compared using reference equality.
Symbol's companion object has an
apply method, so a symbol can be created by writing e.g.
The language has also long included special syntax for this class. Again, the Scaladoc:
For instance, the Scala term 'mysym will invoke the constructor of the Symbol class in the following way: Symbol(“mysym”).
A more formal (and only slightly longer) treatment is in the section 1.3.7 of the Scala Language Specification.
We propose to leave
scala.Symbol in place, but remove the special syntax.
At the time the single-quote syntax was added to Scala, Scala did not yet have string interpolators. One may speculate that if string interpolators had been added first, the single-quote syntax would probably never have existed.
The following changes are already tentatively in place in the latest Scala 2.13 nightlies, for release very soon as part of Scala 2.13.0-RC1:
- deprecate the single quote syntax (PR #7395)
- add a
symstring interpolator, so that we can write e.g.
The second change (the addition of the
sym interpolator) is independent of the first. It would also be possible to simply require users to write
Symbol("foo") (which is five characters longer).
Deprecating the syntax in 2.13 paves the way for removing symbol literals entirely from Scala 2.14 and Scala 3.
(A more radical alternative that was also considered, but isn’t part of the current proposal: the
scala.Symbol class itself could also be deprecated and removed.)
A long discussion on this has already taken place, beginning in December 2017 in this thread started by Martin Odersky:
The main points made in favor:
- The concepts of symbols is not core to the language.
- “[Symbols] don’t really have a purpose in Scala”
- “I am saddened that this feature of Lisp heritage will likely go away, but despite my best efforts I couldn’t find a compelling reason to keep it.”
- Symbols are used in some existing Scala code, but are not used pervasively.
- All syntax has a cost. Keeping the syntax means “necessity for us to keep teaching the concept and for programmers the risk of being puzzled when they see it”
- The syntax clashes (in our minds, if not in the parser) with the
'x'syntax for character literals. “it looks like an unclosed character literal”
- Tooling doesn’t always understand the syntax, especially because of the overlap with the character literal syntax. “I was annoyed more than once by some editor’s syntax highlighting becoming confused”
- Scala 2.13 adds literal types, increasing the spec and implementation footprint of the symbol literal syntax (since it would be strange and inconsistent to have the literals without the corresponding literal types).
- Most DSLs that use symbol literals don’t need interning and could therefore use string literals instead, at the cost of only one additional character per literal.
- Although there is migration cost to use
symor string literals instead, it’s not tricky migration, it’s an easy Scalafix rewrite (or, as a quick-and-dirty alternative that would work in many codebases, even search-and-replace).
Also, Aaron Hawley did an experiment using the Scala community build (described in this comment); he believed the results indicated the change wouldn’t be too disruptive.
The main points against the proposal were:
- The change will break existing code, for no substantial gain.
- Several very popular libraries use symbol literals. Examples include ScalaTest, Play, and Ammonite.
Opening this proposal for discussion by the community to get additional perspectives.