Eval 0.1.0
I released Eval 0.1.0. Eval evaluates Scala 3 code. It’s a Scala 3 port of Eval
class used in sbt.
package example
import com.eed3si9n.eval.Eval
import com.eed3si9n.eval.EvalReporter
import java.nio.file.Paths
@main def main(): Unit =
val eval = Eval(
backingDir = Paths.get("/tmp/classes"),
mkReporter = () => EvalReporter.store
)
val result = eval.evalInfer("2")
println(result.tpe)
println(result.getValue(this.getClass.getClassLoader))
The above prints:
Int
2
You can also pass in the expected type:
package example
import com.eed3si9n.eval.Eval
import com.eed3si9n.eval.EvalReporter
import java.nio.file.Paths
@main def main(): Unit =
val eval = Eval(
backingDir = Paths.get("/tmp/classes"),
mkReporter = () => EvalReporter.store
)
val result = eval.eval("2", Some("scala.Long"))
println(result.tpe)
println(result.getValue(this.getClass.getClassLoader))
The above prints:
Long
2
There’s also a macro that takes a type parameter, and would return a value in that type:
package example
import com.eed3si9n.eval.Eval
case class ServerConfig(port: Int)
@main def main(): Unit =
val x = Eval[ServerConfig](
"example.ServerConfig(port = 8080)")
println(x.port)
The above prints:
8080
background
Around the time when I started Scala in 2009 or 2010, there was an idea of implementing evaluator for Scala code, passing some code as String, which then would evaluate the return some value.
Two examples that pop into my mind are:
- Josh’s Embedding the Scala Interpreter (2009)
- Twitter’s util-eval (2010)
- util-eval mentions “Compiler API” thread (2007)
Since DSL was initially thought to be one of the strengths of Scala, this makes sense. Another use promoted by util-eval, which is now deprecated, was using Scala code to represent configurations.
Scala 2 Reflection API was added later in the history of Scala 2, which includes Toolbox to allow type this of operation, but sbt that was created also during the early era never moved to using it, partly because it was doing mutable operation to fake the position.