Thilo
Thilo

Reputation: 262534

"eval" in Scala

Can Scala be used to script a Java application?

I need to load a piece of Scala code from Java, set up an execution scope for it (data exposed by the host application), evaluate it and retrieve a result object from it.

The Scala documentation shows how easy it is to call compiled Scala code from Java (because it gets turned into to regular JVM bytecode).

But how can I evaluate a Scala expression on the fly (from Java or if that is easier, from within Scala) ?

For many other languages, there is the javax.scripting interface. Scala does not seem to support it, and I could not find anything in the Java/Scala interoperability docs that does not rely on ahead-of-time compilation.

Upvotes: 56

Views: 31804

Answers (6)

ninjagecko
ninjagecko

Reputation: 91092

it's now 2011, and you can do so with scala.tools.nsc.Interpreter see http://blog.darevay.com/2009/01/remedial-scala-interpreting-scala-from-scala/

use scala.tools.nsc.interpreter

Upvotes: 66

gun
gun

Reputation: 1066

I am not sure, if this is a good way, but I solved this problem with using toolbox.parse and toolbox.eval

To have an eval in Scala you have to:

  1. Import scala-reflect

libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.11.7"

  1. Use eval from toolbox:

  import scala.reflect.runtime.currentMirror
  import scala.tools.reflect.ToolBox
  val toolbox = currentMirror.mkToolBox()

  val as = "2*(2+3)"
  val compe = toolbox.eval(toolbox.parse(as))

  println(compe.getClass) // prints class java.lang.Integer
  println(compe) // prints 10

Upvotes: 16

Oswaldo
Oswaldo

Reputation: 523

Scala has added official support to JSR-223 in 2.11 (https://issues.scala-lang.org/browse/SI-874).

So if you still need it after thinking about the considerations made in the currently accepted answer from Daniel Spiewak (about rethinking in a way it is not needed), this should be the official alternative.

Upvotes: 23

Robey Pointer
Robey Pointer

Reputation: 251

You can emulate "eval" by taking scala code, wrapping it in a class, compiling that class, using reflection to create a new instance, and then calling it. It's a little involved, and the scala compiler is very slow (on the order of 2 seconds) to initialize, but it works fine.

There's a library for it here, called "util-eval": https://github.com/twitter/util/

The code in question lives here: https://github.com/twitter/util/blob/master/util-eval/src/main/scala/com/twitter/util/Eval.scala

It works like this:

val sum = Eval[Int]("1 + 1")
// sum will be 2

Upvotes: 16

Kim Stebel
Kim Stebel

Reputation: 42047

You can always use scalac to compile a scala class and then load that class dynamically. But I guess that's not what you're after.

Upvotes: 2

Daniel Spiewak
Daniel Spiewak

Reputation: 55123

Scala is not a scripting language. It may look somewhat like a scripting language, and people may advocate it for that purpose, but it doesn't really fit well within the JSR 223 scripting framework (which is oriented toward dynamically typed languages). To answer your original question, Scala does not have an eval function just like Java does not have an eval. Such a function wouldn't really make sense for either of these languages given their intrinsically static nature.

My advice: rethink your code so that you don't need eval (you rarely do, even in languages which have it, like Ruby). Alternatively, maybe you don't want to be using Scala at all for this part of your application. If you really need eval, try using JRuby. JRuby, Scala and Java mesh very nicely together. It's quite easy to have part of your system in Java, part in Scala and another part (the bit which requires eval) in Ruby.

Upvotes: 52

Related Questions