Scala has symbols - names that start with a single quote \' and which are a kind of string constants.
I know symbols from Ruby (where they start with a colon). In Ru
According to the Scala book, Symbols are interned: "If you write the same symbol twice, both expressions will refer to the exact same Symbol
object."
In contrast, String
s are only interned if they appear in literal form (at least in Java they are, not entirely sure about Scala). So I guess if you do a lot of serialization of String
s that are then put into collections, you might use symbols instead and save yourself some memory.
But I agree with skaffman, I'm not totally convinced of their use.
(In Ruby, Symbol
s are, apart from the meta-programming example you give, often used as keys in Hash
es. In Ruby this is useful because there, String
s are never interned: every String
allocates new memory. In Scala it might be useful, as I mentioned, if you combine it with a lot of (de)serialization so the Java String
s don't get interned as well.)
As already noted, symbols carry-over from other (more) functional languages. Something others have not mentioned is that not only do they fill the role of symbols, but they are also the closest equivalent of keywords (minus the performance advantage maybe). In my opinion, they are more useful as keywords, meaning explicit identifiers.
Below I will include a court description from Clojure docs of keywords and symbols.
Symbols
Symbols are identifiers that are normally used to refer to something else. They can be used in program forms to refer to function parameters, let bindings, class names and global vars. They have names and optional namespaces, both of which are strings. Symbols can have metadata (see with-meta).
Keywords
Keywords are symbolic identifiers that evaluate to themselves. They provide very fast equality tests. Like Symbols, they have names and optional namespaces, both of which are strings. The leading ':' is not part of the namespace or name.
Scala symbols are not as powerful as symbols in some languages. Therefore, they are not as useful either. However, I don't see why they couldn't offer the same meta-programming and performance advantages as keywords. At the very least, they can make your code easier to read.
I suppose you would use them when you want to refer to the name of a thing that isn't an existing identifier in the code. The Scala book gives the example of referring to the name of a database column - it isn't an arbitrary string, it's actually the name of a thing.
It's a bit tenuous, though, I'm not altogether convinced.
Do symbols really fit into Scala?
In the wonderful land of Lisp, code is represented as nested lists of literal objects that denote themselves (strings, numbers, and so on), and symbols, which are used as identifiers for things like classes, functions, and variables. As Lisp code has a very simple structure, Lisp allows the programmer to manipulate it (both at compile-time and run-time). Clearly, when doing this, the programmer will inevitably encounter symbols as data objects.
So symbols are (and need to be) objects in Lisp in any case, so why not use them as hash table keys or as enums as well? It's the natural way of doing things, and it keeps the language simple, as you don't have to define a special enumeration type.
To summarise, symbols are naturally used for code manipulation, enumeration, and keying. But Java people don't use identity as the equivalence relation between hash keys by default (which your traditional Lisp does), so they can just use strings as their keys. Enum types are defined separately in Scala. And finally, code as data isn't supported by the language at all.
So no, my impression is that symbols don't belong in the Scala language. That said, I'm going to keep an eye on the replies to this question. They might still demonstrate a genuine use of symbols in Scala that I can't think of right now.
(Addendum: Depending on the Lisp dialect, Lisp symbols may also be namespace-qualified, which is, of course, an immensely useful feature when manipulating code, and a feature that strings don't have.)
I guess Scala added them because functional languages use them.
They forgot, though, to add the ability of referencing an identifier through a symbol, which is kind of the central point of their existence. There's an experimental feature in Scala 2.8 that gives some of that. I'll quote the relevant part of the API documentation in full:
@experimental
object Invocation
extends AnyRef
A more convenient syntax for reflective invocation. Example usage:
class Obj { private def foo(x: Int, y: String): Long = x + y.length }
You can call it reflectively one of two ways:
import scala.reflect.Invocation._
(new Obj) o 'foo(5, "abc") // The 'o' method returns Any
val x: Long = (new Obj) oo 'foo(5, "abc") // The 'oo' method casts to expected type.
If you call the oo
method and do not give the type inferencer enough help, it will most likely infer Nothing
, which will result in a ClassCastException
.
Author Paul Phillips
I believe comparisons between symbols is faster. If you've used Erlang, symbols are used a tonne when passing around messages and you want something cheap, and fast, that works well ACROSS machine boundaries. I'm not sure in what state remote actors are in Scala, IIRC, they were rather dodgy, but in the future when them in place, symbols could well be very useful in much the same way as they are in Erlang. Also case classes, some of the benefits aren't as apparent, then again, symbols are still cheaper.