OSS and Professional thoughts on migrating to Scala 3

There are two fundamentally different modes of mixed compilation.

The first one, which is not the default, is actually sequential compilation. With JavaThenScala or ScalaThenJava, the Scala and Java compilers are invoked sequentially, each on their own sources, without looking at the sources of the other language (only the class files). This mode can be emulated for 2.13/3 simply by using an additional configuration (sbt) / module (mill) that uses one compiler, while the normal Compile configuration depends on that one and uses the other compiler.

The real mixed compilation involves the Scala compiler running first on all source files, including the Java ones, and typechecking everything at once. It then compiles the Scala sources all the way to bytecode, while it stops after typechecking for Java sources. Finally, the Java compiler runs on the Java sources, reading the bytecode of the Scala sources. That mode requires the Scala compiler to be able to typecheck Java sources, with its type system. As you can imagine, having Scala 3 being able to typecheck Scala 2 source code, or conversely, is completely out of the landscape of realistic possibilities. So no, real mixed compilation of Scala 2 and 3 will not be possible.

5 Likes

Pity the technique used by the Wii to ensure GameCube backwards compatibility isn’t relevant to software. I doubt the Scala 2 typer could be repurposed the way they did with the GameCube processor.

Since the purpose of Scala 2/3 mixed compilation is to support optional Scala 2 dependency, Scala3ThenScala2 mode should be good enough for library authors. Library authors can cross compile their core functionality and runtime, while keep the macro based Scala 2 DSL / facade unchanged.

However, it requires library users to delicately design the dependency of Scala 2/3 sources. Type class derivation should be compile early but macro based DSL should compile later.

I wonder if the build tools can parse the dependency between source files and automatically split them into compilation runs, or raise an error if cyclic dependencies are detected. IIRC, the dependency parser might be able to be implemented in ScalaMeta without nsc nor dotty compiler.