Question

I've been playing around with the new API for the compiler and repl in 2.11 and have hit something weird. Here's my repl output:

Welcome to Scala version 2.11.0-20140415-163722-cac6383e66 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_51).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import scala.tools.nsc.interpreter.IMain
import scala.tools.nsc.interpreter.IMain

scala> import scala.tools.nsc.Settings
import scala.tools.nsc.Settings

scala> val eng = new IMain(new IMain.Factory(), new Settings())
eng: scala.tools.nsc.interpreter.IMain = scala.tools.nsc.interpreter.IMain@649b982e

scala> eng.interpret("val x: Int = 2")
x: Int = 2
res0: scala.tools.nsc.interpreter.IR.Result = Success

scala> eng.valueOfTerm("x")
res2: Option[Any] = Some(2)

scala> eng.typeOfTerm("x")
res3: eng.global.Type = ()Int

scala> eng.typeOfExpression("x")
res4: eng.global.Type = Int

scala> eng.typeOfExpression("x") =:= eng.global.definitions.IntTpe
res6: Boolean = true

scala> eng.typeOfTerm("x") =:= eng.global.definitions.IntTpe
res7: Boolean = false

As you can see, typeOfTerm("x") returns ()Int, but typeOfExpression("x") returns Int. I think it's the case that the type ()Int represents a variable of type Int, but I can't be sure. If someone could confirm that or correct my confusion and maybe direct me to any documentation that talks about this, I'd appreciate it. I looked through the reflection docs that I could find, but didn't have any luck.

Was it helpful?

Solution

In REPL, your val x is not a local definition. It is wrapped in a class or object, which leads to differing behaviors.

Your object X { val x = 2 } has a member x that is a parameterless method type, as if you had def x = 2.

scala> val x: Int = 2
x: Int = 2

scala> $intp.typeOfTerm("x")
res0: $intp.global.Type = ()Int

scala> import $intp.global._
import $intp.global._

scala> $intp.replScope.lookup(TermName("x"))
res2: $intp.global.Symbol = value x

scala> res2.tpe
res3: $intp.global.Type = ()Int

scala> :power
** Power User mode enabled - BEEP WHIR GYVE **
** :phase has been set to 'typer'.          **
** scala.tools.nsc._ has been imported      **
** global._, definitions._ also imported    **
** Try  :help, :vals, power.<tab>           **

scala> intp.replScope.lookup(TermName("x"))
res6: $r.intp.global.Symbol = value x

This is how we're used to seeing it:

scala> .tpe
res7: $r.intp.global.Type = => Int

scala> :phase
Active phase is 'Typer'.  (To clear, :phase clear)

scala> :phase clear
Cleared active phase.

scala> res6.tpe
res8: $r.intp.global.Type = ()Int
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top