X

Sundararajan's Weblog

  • Java
    March 8, 2007

(mis)understaning Scala's singleton types?

Guest Author

I've been reading/playing with Scala. Scala has the concept of "singleton types". If types are considered as sets, singleton types are sets with only one object. A singleton type is expressed in Scala using object.type. To refer to the singleton type the expression for object has to be "stable". Informally, this means the expression that denotes the object should evaluate to the "same object reference" every time it is evaluated.


A simple Scala interactive session to understand singleton types:


This is an interpreter for Scala.
Type in expressions to have them evaluated.
Type :help for more information.
scala> val s = "hello"
s: java.lang.String = hello
scala> val x : s.type = s
x: s.type = hello
scala> val p : s.type = "ss"
<console>:5: error: type mismatch;
found : java.lang.String("ss")
required: s.type
val p : s.type = "ss"
\^

The last command resulted in error because value "p" can not be initialized with any other String other than the one referred by "s" -- because p is of type s.type and not java.lang.String.


Following is another session to understand "stable" path:

This is an interpreter for Scala.
Type in expressions to have them evaluated.
Type :help for more information.
scala> var s = "hello"
s: java.lang.String = hello
scala> val p : s.type = "ss"
:5: error: stable identifier required, but line8$object.s found.
val p : s.type = "ss"
\^

"s.type" is not allowed as a valid type because "s" is not stable - because s is a variable (and not a value) it could be assigned with some other String reference and so "s.type" can not be defined.

So far so good! How about creating a new instance of singleton type? What that could really mean? Let us try another interpreter session:


This is an interpreter for Scala.
Type in expressions to have them evaluated.
Type :help for more information.
scala> val s = "hello"
s: java.lang.String = hello
scala> var p = new s.type()
Exception in thread "main" java.lang.AssertionError: assertion failed: s
at scala.Predef$.assert(Predef.scala:89)
at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transform(RefChecks.scala:619)
at scala.tools.nsc.ast.Trees$Transformer.transform(Trees.scala:1183)
at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transform(RefChecks.scala:635)
at scala.tools.nsc.ast.Trees$Transformer.transform(Trees.scala:1161)
at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transform(RefChecks.scala:635)
at scala.tools.nsc.ast.Trees$Transformer.transform(Trees.scala:1173)
[.... more frames deleted ...]

Okay, the interpreter "crashed". How about the compiler?

object test {
def main(args: Array[String]) {
val s = "hello";
var x = new s.type();
Console.println(x.getClass());
}
}

Surprise! The above code compiled and "x" refers to a (new) empty String! Now, either the interpreter or the compiler is wrong. And so my understanding of singleton types??. Update: Creating objects of singleton types means nothing (please see Martin Odersky's comment below). So, it is an implementation bug.

Join the discussion

Comments ( 2 )
  • martin odersky Friday, March 9, 2007
    Creating an object of a singleton type means nothing really. It should be disallowed. So I would classify this as a bug in the compiler/interpreter.
  • A. Sundararajan Friday, March 9, 2007
    Thanks for the clarification!
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.