Help using the interpreter (IMain) in Scala 2.13

I need some help using an embedded Scala script interpreter.

I’m using Scala 2.13, IMain, and some scripts in an experiment to simplify the work to adapt a Seq of network terms to local terms. I want to use a script because every local system is potentially different. Each local system needs just one script which will change infrequently (months to years) but will run frequently (every few seconds to minutes).

The translation is one network term to zero-or-more local terms, done in a batch. (The starting point is a database table made from the two-column CSV file you imagine, with 100,000 to 1,000,000 network terms. The mapping between the two columns is not profoundly difficult.)

So far I have

  def networkTermsToLocalTerms(shrineTerms:Seq[String]):Map[String, Set[String]] = {
    val settings: Settings = new Settings
    settings.processArgumentString("-Xlint")
    settings.usejavacp.value = true
    settings.deprecation.value = true
    settings.feature.value = true
    settings.fatalWarnings.value = true

    val interpreter: IMain = new IMain(settings,TermReplReporter)
    interpreter.bind("shrineTerms","Seq[String]",shrineTerms)
    val result = interpreter.interpret(script)
    val res0: Option[Any] = interpreter.valueOfTerm("res0")
    res0.get.asInstanceOf[Map[String, Set[String]]]
  }

for a script like

def passThrough(shrineTerms:Seq[String]):Map[String, Set[String]] = {
  shrineTerms.map(term => term -> Set(term)).toMap
}

passThrough(shrineTerms.asInstanceOf[Seq[String]])

Are there some examples of how to use more features of IMain?

For low latency and to get some understanding I’d like to compile the script. interpreter has a compile method - but what does it do after the compile?

Is there some way to avoid the casts?

What changes in Scala3?

What else should I know about this part of Scala?

(iLoveZod13 had a similar question a few weeks back, but solved it by down-shifting to Scala 2.12 to match the examples he found, probably Programmatic Use of Scala REPL | REPL | Scala Documentation . I’m working on a much bigger system, so can’t just shift to the older version. )

Thanks,

David

As an example of using an embedded interpreter you can take look at the ijp-scala-console
It has versions for Scala 2.12, 2.13, and 3:

1 Like

The general answer is that using the REPL in this way is not well supported or defined, and everything is different in Scala 3.

Depending on your use case, it’s easier to recompile a standalone source file.

For script jobs, the runner will save a jar for you, to avoid recompilation.

$ scala -save hello.scala Bob
hello, Bob!

$ ls hello.jar
hello.jar

Ammonite and Scala-cli (which became the default code runner in Scala 3) both have powerful scripting capabilities, definitely worth checking out. I’m not sure what you are trying to do exactly, but Scala-cli can use compiler options and Ammonite has a section on embedding it into other programs.