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:

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.