views:

221

answers:

3

Possible Duplicate:
What are some example use cases for symbol literals in Scala?

What's the purpose of Symbol and why does it deserve some special literal synatx e. g. 'FooSymbol?

+2  A: 

Symbols are interned.

The purpose is that Symbol are more efficient than Strings and Symbols with the same name are refered to the same Symbol object (so having the same hashcode).

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)
michael.kebe
In Java, Strings are also interned.
IttayD
Yep, the in the .NET CLR, too.
michael.kebe
This entry is a little bit misleading; where you say "having the same hashcode", all equal strings have the same hashcode. Where they differ is that they are precisely the same object instance, meaning that comparing them does not involve calling a complex "equals" method which will compare every character; you just need to compare the memory locations (i.e. == in Java or "eq" in Scala).IttayD: That's not true; literal strings are interned, and you can intern strings with String.intern().
Calum
Strings are not 100% always interned http://javatechniques.com/public/java/docs/basics/string-equality.html
Elazar Leibovich
+2  A: 

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

IttayD
For the last example, there's no reason not to use a string instead of a Symbol.
Elazar Leibovich
The reason is that in HTML 'div' is an identifier, not just a random string. That is why I mentioned HTML and not XML (where an element can be of any name). So the reason of the Symbol is semantic. Functionally speaking, there's no difference
IttayD
+5  A: 

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 unweildy 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 Strings 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 Strings 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. Symbols 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 and 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.

Calum