Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unrecognizable code in scala Predef object

Tags:

scala

Can someone please explain the following code in Predef object? Thanks.

scala.`package`     // to force scala package object to be seen.
scala.collection.immutable.List // to force Nil, :: to be seen.
like image 788
Sachin K Avatar asked Dec 07 '13 23:12

Sachin K


2 Answers

(Link). I can only guess. When you use a singleton object as expression, this has the same effect as forcing the evaluation of a lazy val, in other words it will run the object's body if it wasn't yet initialised.

For example:

object Foo {
  println("Foo is launching rockets...")
}

Now when you write just

Foo   // prints `Foo is launching rockets...`

this enforces the evaluation of the contents of Foo.

So my guess is that in Predef this just makes sure that certain things in the scala package object and in List are initialised. Very unlikely something you would bother as a user.

like image 82
0__ Avatar answered Oct 23 '22 12:10

0__


The accepted answer has to be wrong.

Update: The ML provided a couple of helpful links to issues, without saying whether the problem is only runtime dependencies between modules or also compiler-internal or similar.

Predef is imported at compile time to make various definitions available when your source file is compiled. (Update: but still carries some value definitions, and not all its methods are inlined. And in any case, even an inlined usage, of assert for example, will incur a reference to Predef$.MODULE$, because of side-effects at initialization, see below.)

You can turn off that behavior with -Yno-predef. For example,

apm@mara:~/goof$ scala -Yno-predef
Welcome to Scala version 2.10.3 (OpenJDK 64-Bit Server VM, Java 1.7.0_25).
Type in expressions to have them evaluated.
Type :help for more information.

scala> "a" -> 1
<console>:8: error: value -> is not a member of String
              "a" -> 1
                  ^

It has nothing to do with runtime evaluation. Otherwise, everything in Predef and everything it referenced would get loaded before your program got a chance to run.

(Update: yeah, well, guess what.)

In Scala, import is not like #include.

Useful exercise:

scala> :javap -prv scala.Predef$

  private scala.Predef$();
    flags: ACC_PRIVATE
    Code:
      stack=3, locals=1, args_size=1
         0: aload_0       
         1: invokespecial #520                // Method scala/LowPriorityImplicits."<init>":()V
         4: aload_0       
         5: putstatic     #522                // Field MODULE$:Lscala/Predef$;
         8: aload_0       
         9: invokestatic  #526                // Method scala/DeprecatedPredef$class.$init$:(Lscala/Predef$;)V
        12: getstatic     #531                // Field scala/package$.MODULE$:Lscala/package$;
        15: pop           
        16: getstatic     #536                // Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
        19: pop           
        20: aload_0       
        21: getstatic     #540                // Field scala/collection/immutable/Map$.MODULE$:Lscala/collection/immutable/Map$;
        24: putfield      #151                // Field Map:Lscala/collection/immutable/Map$;
        // etc, etc

No doubt my understanding is incomplete.

like image 25
som-snytt Avatar answered Oct 23 '22 13:10

som-snytt