Multiple scala versions in the same project - scala

Apologies if this is a duplicate, I didn't hit on the magic keyword while searching.
I have a project where I pull in various dependencies. One of them (jooq) depends on scala 2.10, whereas my application depends on scala 2.11.x.
Although everything "works", I would like to understand better what are the runtime implications of doing something like this? How will the JVM resolve the different dependencies, and what type of overhead could I be looking at?
I am trying to determine if it's worthwhile to fork jooq, and compile it against 2.11 (assuming it will compile and work under 2.11).

Scala is not binary compatible between major versions (2.10 to 2.11 for example). This means that there are no guarantees that a library that is compiled for Scala 2.10 will work in a project using 2.11. You might be lucky enough that it works, but I would definitely not depend on that luck for any important codebase.
This is the reason why Scala libraries always has got the library version in their name and why SBT has got special syntax for dependencies to get the right library build for the Scala version used.
On a side note Martin Odersky (Scalas "father") has been proposing a solution to this problem during the year, storing an intermediate representation along with the byte code to allow automagical recompilation to a newer Scala version.

You have the possible danger of runtime exceptions.
As Scala 2.10 and 2.11 are quite similiar the danger is not as big as it has been with 2.9 to 2.10 or 2.8 to 2.9 but it still is there and if you want to do something that is meant to be prodcution code, you definitly should try to raise jooq to 2.11.

Related

Version agnostic way to convert from Java to Scala collections and back

Almost each Scala version changes the way collection conversion happens in a non-backward compatible way. Is there a better solution that is version agnostic and does not depend on Scala distribution?
I don't mind using some 3rd party libraries.
Just use the scala-collections-compat library and then you can use import scala.jdk.CollectionConverters._ on Scala 2.11, 2.12 & 2.13.

Can I compile a string containing Scala code to machine code using Scala Native as a library of my program?

I succeed compiling a scala project to machine code using Scala Native.
But I want to generate some executable code at runtime (I plan to implement a standalone compiler from a scala-like language to machine code).
The goal is to have a self-hosted language, independent of JVM.
Is it possible to somehow embed the Scala Native compiler in my project?
As described in https://www.scala-native.org/en/v0.4.0/contrib/build.html,
The build of Scala Native contains the following JVM-based portions of which the 1st, 3rd, and 4th seem like they would be necessary for a Scala Native compiler embedded in your own compiler:
The Scala Native sbt plugin and its dependencies (directory names are in parentheses). These are JVM projects.
sbtScalaNative (sbt-scala-native)
tools
nir, util
nirparser
testRunner (test-runner)
So Scala Native is not independent of JVM as OP's question seeks. Conversely, studying the NIR (scala-Native Intermediate Representation) portions of the Scala Native codebase might indicate a point (somewhere near the emission of NIR onward) to factor out a nonJVM NIR-to-LLVM backend. Then OP's “self-hosted language” that compiles NIR to LLVM IR to machine code “from a scala-like language to machine code” as OP's question seeks might be possible, as derived from some backend extract/fragment of Scala Native's codebase after the parser, perhaps after the AST, which is dependent on Scala(-proper)'s JVM-based parser, whereas from NIR onward is in the JVM simply because the parser and AST were already within the JVM.

Is there a conversion/migration guide for Scala v2.9 to current v2.12.x?

There is a Scala library I would like to use (PiStache) that was written for Scala v2.9 and hasn't been updated in 7 years.
Q: Can anyone point to a conversion or migration guide for Scala v2.9 to the most current v2.12.x?
I have searched the web for any conversion or migration guides, and haven't found any. The only option I see is going through the successive release notes hoping they list incompatibilities.
I have found various discussion threads that describe why there there are incompatibilities between minor versions, but no succinct list of changes that need to be made. Of course, I could take the trial and error approach and simply compile the library under 2.12.x and then respond to error messages, but I'm hoping to avoid that (potentially) time consuming process.
The best migration guide I found is here (2 parts), focusing on 2.9 -> 2.10 migration:
http://www.tomergabel.com/Scala210MigrationCaseStudyPartI.aspx
http://www.tomergabel.com/Scala210MigrationCaseStudyPartII.aspx
tl;dr: Most of the migration effort is tied to libraries, and if library authors have newer (compatible) versions then you are good. But there are a variety of small changes to Scala library that you might stumble on:
The Scala class library itself has a number of changes you ought to be aware of before migrating to 2.10. The really big change is that Scala actors are deprecated in favor of Akka. You can still use them by importing the scala-actors artifact from the Scala 2.10 distribution, but it is recommended to migrate fully to the new actor system as this is also likely to be obsoleted by 2.10.1. The gentle folk at Typesafe have provided a very comprehensive migration guide to assist your efforts.
The less prevasive API changes we ran into include:
List.elements is deprecated in favor of List.iterator;
TraversableOnce.toIndexedSeq no longer takes a type argument. This was actually quite pervasive in our codebase, causing plenty of compilation errors, and is easily worked around by removing the type parameter (which is extraneous to begin with);
Scala actors' Actor.receive method is now public (previously protected). This had to be rectified in pretty much all of our existing actors by removing the protected modifer;
Occasional subtle API changes requiring minor code fixes, e.g. Enumeration and Mapping.
Regarding 2.10 -> 2.11 (from Release Notes, emphasis added):
Code that compiled on 2.10.x without deprecation warnings should compile on 2.11.x (we do not guarantee this for experimental APIs, such as reflection)
Regarding 2.11 -> 2.12 (from Release Notes, emphasis added):
Although Scala 2.11 and 2.12 are mostly source compatible to facilitate cross-building, they are not binary compatible. This allows us to keep improving the Scala compiler and standard library.
CAUTION: For anyone using Apache Spark, note that the latest version 2.3.0 is not compatible with the latest version of Scala 2.12.x, so you are forced to use Scala 2.11.x until this changes (fairly soon, from discussions I've seen).

How did the scala compiler first compile?

I read the scala compiler recently.
Scala compiler written by Scala.
I realized. How did it first compile?
Scala didn't exist yet...right?
The first version of the Scala compiler was written in Java.
I read the scala compiler recently.
Scala compiler written by Scala.
I realized. How did it first compile?
It was compiled with the previous version of the Scala compiler, which was written in Java. Note that the name of the current Scala compiler is "nsc", which stands for "new Scala compiler" – that should give you a hint that there existed a compiler before the current one. And that compiler was written in Java.
However, it is not actually necessary that the compiler written in Scala is the second compiler. It could also be the first compiler. How would that work?
Well, the first option is that before there was a Scala compiler, there could have been a Scala interpreter. Then, you could have used that interpreter to run the Scala compiler and compile itself.
The second option is that the compiler could have been translated by hand into another language. Technically speaking, this is also compilation or interpretation (depending on how exactly you perform it), just done by a human brain instead of a program. Niklaus Wirth did this with the first version of the Oberon compiler. The Oberon compiler was always written in Oberon, there was never a different version. It was hand-translated by his students into a Fortran dialect, the translated version compiled by the Fortran compiler, then the compiled version was used to compile the original version.
Scala didn't exist yet...right?
That is a completely different question, actually. A language can exist without there ever having been an implementation. For example, Plankalkül existed for ~30 years, until it was implemented for the very first time. ISWIM has never been implemented AFAIK, and yet, it is a very important programming language.

Can Scala.js not compile itself?

I'm going through the tutorial and it looks like Scala.js only runs under sbt.
Are there bits of Scala.js (or the Scala environment generally) that are not written in Scala? Or cannot all the necessary bits go through Scala.js for some other reason? What am I missing?
Mostly, this is because the Scala compiler uses too many parts of the JDK that have not been ported to Scala.js (yet). Some of these parts, most notably related to reading files (in the classpath, and source files), which cannot be implemented in JavaScript as such (though could be implemented for one particular platform, such as Node.js).
There is also the dependency on ASM, a Java bytecode manipulation library written in Java. Even though Scala.js compiles to JavaScript, the Java bytecode is still used for separate compilation (symbol lookup in previously compiled parts, such as libraries).
So, even though the Scala.js specific parts are written in a platform-independent way (e.g., we test that the Scala.js optimizer can optimize itself), there are a lot of parts in scalac that do not work out-of-the-box in Scala.js.