Compile and execute Scala code at runtime - scala

Is is possible to compile and execute scala code as a string at runtime either in Scala or in Java?
My idea is to build a DSL using Scala then let Java programmers use the DSL inside Java.
I heard that the class scala.tools.nsc.Interpreter can do something like that, but when I imported it inside my scala file, I got "object tools is not a member of package scala."
So could anybody give me a hint?

In 2.10.0 we expose Scala reflection API, which among everything else includes a runtime compilation facility. More details can be found here: Generating a class from string and instantiating it in Scala 2.10.

I recommend you twitter-util's Eval

For scala3 this can be now achieved with dotty:
https://index.scala-lang.org/lampepfl/dotty
https://github.com/lampepfl/dotty
https://dotty.epfl.ch/docs/internals/overall-structure.html
The sbt dependency is e.g. "org.scala-lang" %% "scala3-compiler" % "3.1.3"

Related

Is "they use sbt, an IDE, and other tools as their interface to the compiler" contrary to "therefore they may not even have scalac installed"?

https://docs.scala-lang.org/overviews/compiler-options/index.html says
Scala compiler scalac offers various compiler options, also referred to as compiler flags, to change how to compile your program.
Nowadays, most people are not running scalac from the command line. Instead, they use sbt, an IDE, and other tools as their interface to the compiler. Therefore they may not even have scalac installed, and won’t think to do man scalac.
Does "the compiler" refer to scalac?
If yes, is "they use sbt, an IDE, and other tools as their interface to the compiler" contrary to "therefore they may not even have scalac installed"?
Does sbt rely on scalac?
Thanks.
Scala compiler can be accessed programmatically via an API packaged by scala-compiler.jar dependency, hence tools such as IDEs and SBT can implement their own client frontends over this API to drive compiler functionality. scalac is just a bash script that executes scala.tools.nsc.MainClass class from scala-compiler.jar.
Does sbt rely on scalac?
No, sbt uses compiler API directly. One of the key concepts to understand regarding sbt is that the build definition is itself Scala code, either vanilla or DSL, but Scala nevertheless. The version of Scala used to compile the build definition is separate from the version of Scala used to compile project proper. The build definition source code in build.sbt and project/*.scala will be compiled using Scala version specified indirectly via sbt.version=1.2.8 setting in project/build.properties, whilst project source code proper in src/main/scala/* will be compiled using Scala version specified directly via scalaVersion := "2.13.1" setting in build.sbt. Note how they can indeed differ. Think of the build definition as simply another Scala app which uses sbt API for its implementation.

Scala SBT to compile DSL into Scala or Java code

There are two cases I have where some DSL specific code needs
to be compiled into Scala and/or Java code. Is there a ready
reference example that demonstrates
how to specify dependency relation
executing a relevant command to compile the DSL
One case is that of an ONCRPC IDL compiler. A ".x"
IDL specification file is compiled into Java. Another case
is of compiling a state map DSL (SMC) code into Scala.
While learning Scala and Functional programming, and at
the same time applying to SBT seems steep, and need help.

Necessary to export Quasiquotes dependency for exported macro libraries on Scala 2.10?

I just updated a project which was using macro-paradise 2.0 snapshot under 2.10; with the final version of macro-paradise 2.0 it tells me the following when I compile under 2.10 (not 2.11):
Quasiquotes in macro paradise for Scala 2.10 require a dependency on a supporting library. Add the following line to your SBT build: libraryDependencies += "org.scalamacros" %% "quasiquotes" % "2.0.0"
Now I'm worried because that dependency turns up as a regular dependency of my published Maven artifact. Is this really so? Or isn't Quasiquotes perhaps just a compile-time dependency that should not be needed for the published artifact?
If so, should I go through these hoops to get rid of the artifact, i.e. % "compileonly"?
Macros that use quasiquotes provided by recent versions of paradise for Scala 2.10, i.e. 2.0.0-M4+, including 2.0.0 and later ones, will almost always require the supporting library to be on classpath when expanding (very simple quasiquotes don't require the library, but that's quite rare).
Therefore if you want users of your library to also use macros that you've written with quasiquotes, you'll need to export "org.scalamacros" %% "quasiquotes" % "2.x.y" in your pom file or rely on someone else to provide this dependency for your users.
Well, I just tried the approach in the linked question to create a special "compileonly" configuration and thus remove it from the exported POM. It was possible to use the library in Scala 2.10 even with Quasiquotes absent.

class java.lang.RuntimeException/Scala class file does not contain Scala annotation

I'm trying to execute a scala code using scala 2.10.2, the code uses some jar libraries compiled with sbt.
I get the following error:
scala: error while loading Order, class file '..\prestashop-scala-client-0.2.4\target\prestasac-0.2.4.jar(co/orderly/prestasac/representations/Order.class)' is broken
(class java.lang.RuntimeException/Scala class file does not contain Scala annotation)
Sources of the prestasac-0.2.4.jar are on github: Order.class
Is there something to do to fix this issue ?
Thank you
Looks like the library is configured to compile against Scala 2.9.1. Major versions of Scala are not binary compatible.
I put the necessary SBT changes here: https://github.com/mpartel/prestashop-scala-client/commit/e9a1df40bfe35518aaebac899e438b9b6fa6d728

Compiling Java annotations with sbt

I've created Java annotations (since I need run time retention) under $PROJECT/src/main/java and my scala codewhich uses these java annotations us under $PROJECT/src/main/scala. The Java annotation thus created also makes use of a Java ENUM as it's value.
If I compile the project then sbt doesn't seem to compile the Java annotations first and errors out on each usage of the enum in annotations. If I comment out all usages of the Java enum in annotations in scala code and do a compile, uncomment enum usage and compile again it all works fine.
How do I ensure that sbt compiles my java annotations and enum (i.e. $PROJECT/src/main/java) before attempting to compile scala code when doing a clean build?
EDIT: I have a bare bones build.sbt and am using sbt 0.11.2
Some good news: This is a known issue and has been resolved.
Some bad news: It's resolved in 2.10 and the fix may not be backported to 2.9.3 (quoting Paul Phillips in the issue thread):
I've tagged this for backporting, which is not a guarantee; I don't
have time to do it right now but I expect to in the near future.
Some good news: If you're stuck on pre-2.10 and your Java sources don't depend on your Scala sources, you can just add the following to your build.sbt and all is well:
compileOrder := CompileOrder.JavaThenScala
Some bad news: If you're stuck on pre-2.10 and your Java sources do depend on your Scala sources, I'm pretty sure you're out of luck, and the comment-compile-uncomment trick is probably your best bet.
I'll bet you're facing SI-2764. This has been fixed in Scala 2.10.
In the meantime, create a separate sub-project for your Java annotations, and depend on this from the project containing the Scala code.. Then the Scala compiler will only process the .class files, rather the .java files.