Purpose of Scala's Symbol?
Symbols are used where you have a closed set of identifiers that you want to be able to compare quickly. When you have two String
instances they are not guaranteed to be interned[1], so to compare them you must often check their contents by comparing lengths and even checking character-by-character whether they are the same. With Symbol
instances, comparisons are a simple eq
check (i.e. ==
in Java), so they are constant time (i.e. O(1)) to look up.
This sort of structure tends to be used more in dynamic languages (notably Ruby and Lisp code tends to make a lot of use of symbols) since in statically-typed languages one usually wants to restrict the set of items by type.
Having said that, if you have a key/value store where there are a restricted set of keys, where it is going to be unwieldy to use a static typed object, a Map[Symbol, Data]
-style structure might well be good for you.
A note about String
interning on Java (and hence Scala): Java String
s are interned in some cases anyway; in particular string literals are automatically interned, and you can call the intern()
method on a String
instance to return an interned copy. Not all String
s are interned, though, which means that the runtime still has to do the full check unless they are the same instance; interning makes comparing two equal interned strings faster, but does not improve the runtime of comparing different strings. Symbol
s benefit from being guaranteed to be interned, so in this case a single reference equality check is both sufficient to prove equality or inequality.
[1] Interning is a process whereby when you create an object, you check whether an equal one already exists, and use that one if it does. It means that if you have two objects which are equal, they are precisely the same object (i.e. they are reference equal). The downsides to this are that it can be costly to look up which object you need to be using, and allowing objects to be garbage collected can require complex implementation.
Symbol
s are interned.
The purpose is that Symbol
are more efficient than String
s and Symbol
s with the same name are refered to the same Symbol
object instance.
Have a look at this read about Ruby symbols: http://glu.ttono.us/articles/2005/08/19/understanding-ruby-symbols
You can only get the name of a Symbol
:
scala> val aSymbol = 'thisIsASymbol
aSymbol: Symbol = 'thisIsASymbol
scala> assert("thisIsASymbol" == aSymbol.name)
It's not very useful in Scala and thus not widely used. In general, you can use a symbol where you'd like to designate an identifier.
For example, the reflection invocation feature which was planned for 2.8.0 used the syntax obj o 'method(arg1, arg2)
where 'o' was a method added to Any and Symbol was added the method apply(Any*) (both with 'pimp my library').
Another example could be if you want to create an easier way to create HTML documents, then instead of using "div" to designate an element you'd write 'div. Then one can imagine adding operators to Symbol to make syntactic sugar for creating elements