0

Groovy

Groovy comes with a compiler called groovyc. For each script, groovyc generates a class that extends groovy.lang.Script, which contains a main method so that Java can execute it. The name of the compiled class matches the name of the script being compiled.

For example, with this HelloWorld.groovy script:

println "Hello World"

That becomes something like this code:

class HelloWorld extends Script {
    public static void main(String[] args) {
        println "Hello World"
    }
}

Scala

Scala comes with a compiler called scalac.

For example, with the same HelloWorld.scala script:

println("Hello World")

The code is not valid for scalac, because the compiler expected class or object definition, but works in the Scala REPL Interpreter. How is possible? Is it wrapped in a class before the execution?

Erik Kaplun
  • 37,128
  • 15
  • 99
  • 111
Arturo Herrero
  • 12,772
  • 11
  • 42
  • 73
  • 1
    Are you asking what *Java* code gets generated by `scalac`? Are you sure that `scalac` actually generates Java code? I would assume it generates Java bytecode (that is, `.class` files) directly. – Daniel Pryden Mar 19 '12 at 17:20
  • `println("Hello World")` is not a valid scala class, so scalac will refuse to compile it (although the scala REPL will "interpret" it) – Paolo Falabella Mar 19 '12 at 17:30
  • 1
    I think there's a general understanding problem here. Scala is NOT a scripting language, so there are no Scala-Scripts. Scala is a statically typed programming language that gets compiled to jvm bytecode. – drexin Mar 19 '12 at 18:02
  • @drexin See Chapter 2, section 4 of Odersky et al.'s *Programming in Scala*, "Write some Scala scripts"... I think they would disagree :) You don't use `scalac` for it though. – Luigi Plinge Mar 19 '12 at 21:07
  • @LuigiPlinge okay, you're right ;-). – drexin Mar 20 '12 at 10:02

3 Answers3

7

The code in a Scala-Script is first placed in a Scala object, then compiled to JVM-Bytecode and at last executed. You can see the generated Scala object by writing scala -Xprint:parser my_file.scala:

package <empty> {
  object Main extends scala.ScalaObject {
    def <init>() = {
      super.<init>();
      ()
    };
    def main(argv: Array[String]): scala.Unit = {
      val args = argv;
      {
        final class $anon extends scala.AnyRef {
          def <init>() = {
            super.<init>();
            ()
          };
          println("hello world")
        };
        new $anon()
      }
    }
  }
}
kiritsuku
  • 52,967
  • 18
  • 114
  • 136
2

scalac will compile your code to java bytecode. println("Hello World") is not by itself a valid scala program, so scalac will not compile it. You can do:

object Test extends App {
  println("Hello World")
}

or

object Test {
  def main(args: Array[String]) {
    println("Hello World")
  }
}

You can then run the output with scala Test. Running the scala "interpreter" on a file that only contains the println("Hello World") line will basically wrap it in an object (transforming it into the first form we've seen above), compile it and run it for you under the hood.

Note that (even though the code looks very similar to a Hello World console application in java) the resulting compiled program is not the same thing that would result from the compilation of this java

/*  note: this is Java code */
/* this does NOT compile to the same bytecode as the previous scala example*/
public class Test {
    public static void main (String args[]) {
        System.out.println ("Hello World");
    }
}
Paolo Falabella
  • 24,914
  • 3
  • 72
  • 86
1

Once you successfully compile a file with scalac, you can use javap, the java class file disassembler, to view the generated class and method signatures (Edit: thanks to @Luigi for pointing out that it is generated signatures, not code). That is, scalac HelloWorld.scala followed by javap HelloWorld.

doelleri
  • 19,232
  • 5
  • 61
  • 65