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).
Summary
We propose to deprecate, then later remove, the single-quote 'foo
syntax for
constructing instances of scala.Symbol
.
Background
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. Symbol("foo")
.
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.
Proposal details
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
sym
string interpolator, so that we can write e.g.sym"foo"
instead of'foo
(PR #7495)
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.)
Discussion
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
Symbol()
orsym
or 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.
Conclusion
Opening this proposal for discussion by the community to get additional perspectives.