"eval" in Scala

JavaScalaScriptingEmbedding

Java Problem Overview


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.

Java Solutions


Solution 1 - Java

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/</strike>

use scala.tools.nsc.interpreter

Solution 2 - Java

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.

Solution 3 - Java

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.

Solution 4 - Java

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

Solution 5 - Java

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

Solution 6 - Java

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThiloView Question on Stackoverflow
Solution 1 - JavaninjageckoView Answer on Stackoverflow
Solution 2 - JavaDaniel SpiewakView Answer on Stackoverflow
Solution 3 - JavaOswaldoView Answer on Stackoverflow
Solution 4 - JavaRobey PointerView Answer on Stackoverflow
Solution 5 - JavagunView Answer on Stackoverflow
Solution 6 - JavaKim StebelView Answer on Stackoverflow