Tuesday, January 5, 2010
Symbols
Scala has what are called symbolic literals. A symbol is very similar to a String except that they are cached. So symbol 'hi will be the same object as 'hi declared a second time. In addition there is special syntax for creating symbols that requires only a single quote.
As odd as this may appear at first glance there are some good use cases for symbols.
I hope that makes sense :)
As odd as this may appear at first glance there are some good use cases for symbols.
- Save memory
- Extra semantics. Semantically they are the same object where "hi" is not necessarily the same as "hi" so 'hi has some extra semantics meaning this is the one an only 'hi object.
- Shorter syntax. This can be useful when designing DSLs
- Identifier syntax. When using the simpler syntax the symbol will be a valid Scala identifier so it can be good when intending to reference methods or variable, perhaps in a heavily reflection based framework
I hope that makes sense :)
- // This is the long way to create a symbol object
- scala> Symbol("hi")
- res10: Symbol = 'hi
- // This is the short way. The symbol must be a legal Scala symbol (like a method name or value/variable name)
- scala> 'hi
- res11: Symbol = 'hi
- // If you *need* characters in a symbol that are not legal in Scala identifiers the Symbol
- // object has a factory method for that purpose
- scala> Symbol("hi there")
- res12: Symbol = 'hi there
- // Not legal
- scala> 'hi there
- < console>:5: error: value there is not a member of Symbol
- 'hi there
- ^
- // quotes are not legal for identifiers
- scala> '"hi there"
- < console>:1: error: unclosed character literal
- '"hi there"
- ^
- < console>:1: error: unclosed string literal
- '"hi there"
- ^
- scala> 'hi\ there
- < console>:5: error: value \ is not a member of Symbol
- 'hi\ there
- ^
- // You can extract out the string from the symbol if desired quite easily
- scala> 'hi match { case Symbol(b) => b}
- res14: String = hi
- // A simpler way to get the string
- scala> 'hi.toString drop 1
- res0: String = hi
Subscribe to:
Post Comments (Atom)
3 comments:
An even simpler way to get the string:
Reply Delete'hi.name
Literal String instances are also cached by the compiler. The intern method allows to internalize strings created at runtime to get unique reference.
Reply DeleteSo I think that on the JVM symbols are useless. Perhaps they were introduced for .Net sake?
One thing to have in mind: symbols in Scala pre-2.8 are implemented as weak references in a hashmap. This could pose some performance problems.
Reply DeleteOne also ought to be careful with frameworks which use reflection to construct objects (like XStream) as this could possibly cause consistency issues when two different symbol objects with the same string exist:
val s = 'symbol
println(s == s.getClass.getConstructors().first.newInstance("symbol"))