tags:

views:

108

answers:

3

When trying to figure how a library works, implicit conversions are confusing. For example, looking at an expression like 'val foo: Foo = 1', what converts 1 to Foo?

Is it possible to instruct the scala library (or REPL) to print out the code paths that are executing while evaluating an expression?

+7  A: 

You can add "-Xprint:typer" to the compiler command line (or "-Ybrowse:typer" for a swing GUI browser) to see the code with the conversions explicitly applied.

Mitch Blevins
+2  A: 

As an alternative to printing out the conversions, one must realize implicits can't just come out of the blue. You have to bring them into scope in some way. The alternatives are:

  1. Explicit import statement. Watch out for import x.y._ when y is an object, as this is the only way to bring in an implicit into scope.
  2. The object companion of the class that is being converted into something else.
  3. The object companion of the target class, as long as that target is made explicit somehow (such as in your example).

Note that the object scala.Predef is all imported into scope by default, which is how Scala's default implicits get into scope.

Daniel
about (1). actually, this question stems from the fact that to use scalacheck you 'import org.scalacheck._' and then you can do things like "val vowel: Gen[Char] = 'A' | 'E' | 'I' | 'O' | 'U' | 'Y'", which obviously uses implicit conversions. It turns out that one of the scalacheck files has 'import Gen.{value,...}' (value is the implicit method that does the conversion)
IttayD
I doubt that import is the relevant one. I'd look inside Gen's object companion for an implicit in this case.
Daniel
Yes, from the companion object, but I didn't need to do 'import org.scalacheck.Gen._' to get it, so importing the implicit was implicitly done (pun intended)
IttayD
A: 

scalac -print prints the code after implicit type conversions where applied.

class A{
    val x : String = "hi" drop 1 
}

Will result in:

package <empty> {
  class A extends java.lang.Object with ScalaObject {
    @remote def $tag(): Int = scala.ScalaObject$class.$tag(A.this);
    private[this] val x: java.lang.String = _;
    <stable> <accessor> def x(): java.lang.String = A.this.x;
    def this(): A = {
      A.super.this();
      A.this.x = scala.this.Predef.forceRandomAccessCharSeq(
        scala.this.Predef.stringWrapper("hi").drop(1));
      ()
    }
  }
}
Thomas Jung