Alternatives to quoted symbols

As I understand, the Symbol data type is being removed from Scala 3, is that right? Is it being replaced by any alternative?

Symbol literals are no longer supported. The scala.Symbol class still exists, so a literal translation of the symbol literal 'xyz is Symbol("xyz") . However, it is recommended to use a plain string literal "xyz" instead. (The Symbol class will be deprecated and removed in the future).

per https://dotty.epfl.ch/docs/reference/dropped-features/symlits.html

Oh, I see, the Symbol type is staying around for a while, just the literal syntax is being removed. Does anyone know why it’s being removed?

1 Like

Symbol literals are fairly rarely used, and wasn’t seen to carry its weight as one of the few literal types – apart from Symbol, there are Integer, Long, Double, Char, Boolean, String/interpolation, multiline string/interpolation. Symbol is much less common than the others.

:cry:

1 Like

What is your use case that required symbols?

The main difference to a string literal is, that it is always interned, making comparisons minimally faster, which can also be achieved by calling .intern on a string.
If you want to prevent mix ups with strings by type checking, Scala 3 will have opaque type aliases, which will solve this problem better.

1 Like

Does anyone remember what the original use case for Symbol type and the reader syntax for it back in Scala 0.1?

My use case is not very profound. It is simply to represent expression trees such as the following.

Not(Or(And(’A, ’C), And(’B, ’C), And(’B, ’D)))

parse-tree

The compiler can do checks on symbols that it can’t do on strings, doesn’t it? So I can’t recommend replacing symbols by strings. I would probably stick to symbols or replace them by some other structure like objects or classes.

Also when it comes to Scala 3 maybe there will be enums from dotty.

https://www.scala-lang.org/blog/2018/04/19/scala-3.html

Scala 1.8 according to the documentation. The motivation was probably shorter syntax, faster comparisons, less memory usage, etc. Efficiency isn’t really exercised as Symbols are mostly used just as syntactically shorter Strings in non-performance critical code. Thus the alternative most of the time is to just use plain Strings.

Another argument against string literals is that it is harder to do safe refactoring.

How do symbols help in refactoring? They aren’t limited to a set of values like enums, they can have all the same values a string can, only difference is that they wrap it in a Symbol class. Any additional checks the compiler can do are also provided by opaque type aliases, but without additional class instances.

Also you can make Symbol out of a String easily (even by an implicit conversion). Opaque type aliases let you enforce additional constraints when converting a String into such type alias.

  implicit def string2symbol(str: String): Symbol =
    Symbol(str)

  def helloSymbol(sym: Symbol): Unit =
    println(sym)

  def main(args: Array[String]): Unit = {
    helloSymbol("this wasn't a Symbol originally")
  }

This could be seen as a weak or strong argument, depending on coding style that is enforced in your project. From my experience I can tell that many people do whatever they see as convenient, so they wouldn’t avoid using such implicit conversion. Especially because such implicit conversion is local and not modifying anyone else’s code, thus viewed as non-intrusive.