How to setup different Scala versions on the same machine? - scala

I want to follow the book on Scala[1] but it uses Scala 3 and I have Scala 2 installed. I want to use both the versions, something on the lines of python2 and python3.
I tried installing Scala3 on my local using the official source but I could only grasp the project-level working directory. The sbt prompt does not work like a REPL would and I can only open REPL using Scala 2 (I checked the version everytime).
How do I open the REPL of Scala3 given I cannot uninstall Scala2?

The sbt prompt does not work like a REPL
If you execute sbt console from within project directory it will drop you into REPL version corresponding to the project's scalaVersion. For example, executing sbt console within project created with sbt new lampepfl/dotty.g8 would start Scala 3 REPL.
but I could only grasp the project-level working directory
For system-wide installation first install coursier and then execute cs install scala3-repl. This will install Scala 3 REPL alongside the Scala 2 one. Now Scala 3 REPL can be started with scala3-repl command whilst Scala 2 REPL simply with scala command.

Related

How to run Scala 3 applications in the command line with Coursier

If you follow the steps at the official Scala 3 sites, like Dotty or Scala Lang then it recommends using Coursier to install Scala 3. The problem is that neither or these explain how to run a compiled Scala 3 application after following the steps.
Scala 2:
> cs install scala
> scalac HelloScala2.scala
> scala HelloScala2
Hello, Scala 2!
Scala 3:
> cs install scala3-compiler
> scala3-compiler HelloScala3.scala
Now how do you run the compiled application with Scala 3?
Currently there does not seem to be a way to launch a runner for Scala 3 using coursier, see this issue. As a workaround, you can install the binaries from the github release page. Scroll all the way down passed the contribution list to see the .zip file and download and unpack it to some local folder. Then put the unpacked bin directory on your path. After a restart you will get the scala command (and scalac etc) in terminal.
Another workaround is using the java runner directly with a classpath from coursier by this command:
java -cp $(cs fetch -p org.scala-lang:scala3-library_3:3.0.0):. myMain
Replace myMain with the name of your #main def function. If it is in a package myPack you need to say myPack.myMain (as usual).
Finally, it seems that is possible to run scala application like scala 2 version using scala3 in Coursier:
cs install scala3
Then, you can compile it with scala3-compiler and run with scala3:
scala3-compiler Main.scala
scala3 Main.scala
This work-around seems to work for me:
cs launch scala3-repl:3+ -M dotty.tools.MainGenericRunner -- YourScala3File.scala
This way, you don't even have to compile the source code first.
In case your source depends on third-party libraries, you can specify the dependencies like this:
cs launch scala3-repl:3+ -M dotty.tools.MainGenericRunner -- -classpath \
$(cs fetch --classpath io.circe:circe-generic_3:0.14.1):. \
YourScala3File.scala
This would be an example where you use the circe library that's compiled with Scala 3. You should be able to specify multiple third-party libraries with the fetch sub-command.

How to install scala 2.12

There are multiple binary incompatible scala 2 versions, however the document says the installation is either via IDE or SBT.
DOWNLOAD SCALA 2
Then, install Scala:...either by installing an IDE such as IntelliJ, or sbt, Scala's build tool.
Spark 3 needs Scala 2.12.
Spark 3.1.2 uses Scala 2.12. You will need to use a compatible Scala version (2.12.x).
Then how can we make sure the scala version is 2.12 if we install sbt?
Or the documentation is not accurate and it should be "to use specific version of scala, need to download specific scala version on your own"?
Updates
As per the answer by mario-galic, in ONE-CLICK INSTALL FOR SCALA it is said:
Installing Scala has always been a task more challenging than necessary, with the potential to drive away beginners. Should I install Scala itself? sbt? Some other build tools? What about a better REPL like Ammonite? Oh and before all that I need to install Java?
To solve this problem, the Scala Center contracted Alexandre Archambault in January 2020 to add a one-click install of Scala through coursier. For example, on Linux, all we now need is:
$ curl -Lo cs https://git.io/coursier-cli-linux && chmod +x cs && ./cs setup
The Scala version is specified in the build.sbt file so SBT will download the appropriate version of Scala as necessary.
I personally use SDKMAN! to install Java and then SBT.
The key concept to understand is the difference between system-wide installation and project-specific version. System-wide installation ends up somewhere on the PATH like
/usr/local/bin/scala
and can be installed in various ways, personally I recommend coursier one-click install for Scala
curl -Lo cs https://git.io/coursier-cli-linux && chmod +x cs && ./cs setup
Project-specific version is specified by scalaVersion sbt settings which downloads Scala to coursier cache location. To see the Scala version and location used by the particular project try show scalaInstance which
inspect scalaInstance
[info] Task: sbt.internal.inc.ScalaInstance
[info] Description:
[info] Defines the Scala instance to use for compilation, running, and testing.
Scala should be binary compatible within minor version so Spark 3 or any other software built against any Scala 2.12.x version should work with any other Scala 2.12.x version where we have major.minor.patch. Note binary compatibility is not guaranteed for internal compiler APIs, so for example when publishing compiler plugins the best practice is to publish it against full specific Scala version. For example notice how kind-projector compiler plugin is published against full Scala version 2.13.6
https://repo1.maven.org/maven2/org/typelevel/kind-projector_2.13.6/
whilst scala-cats application-level library is published against any Scala 2.13.x version
https://repo1.maven.org/maven2/org/typelevel/cats-core_2.13/
Similarly spark is published against any Scala 2.12.x version
https://repo1.maven.org/maven2/org/apache/spark/spark-core_2.12/
Regarding system-wide installation one trick I do for quick switching of versions is to put scala-runners on the PATH and then different versions can be launched via --scala-version argument
scala --scala-version 2.12.14
Using coursier or scala-runners you can even switch JDK quickly via -C--jvm for example
scala --scala-version 2.12.14 -C--jvm=11
For a project, there should be no need to download manually a specific version of Scala. sbt either directly or indirectly via an IDE will download all the dependencies behind the scenes for you, so the only thing to specify is sbt setting scalaVersion.
Using Python as analogy to Scala, and Pipenv as anology to sbt, then python_version in Pipfile is similar to scalaVersion in build.sbt. After executing pipenv shell and pipenv install you end up with project-specific shell environment with project specific Python version and dependencies. sbt similarly downloads project specific Scala version and dependencies based of build.sbt although it has no need for lock files or for modifying your shell environment.

Running scala in cmd makes i look like I am missing 'build.sbt'

I'm trying to run Scala in my command line.
I checked my java, went to the Scala website, downloaded and installed it, updated my environment variables.
So far the only thing different from guides online is that the folder where sbt is installed does not include a "lib" folder.
I then run sbt command in my prompt, and I get this message:
It looks like I'm missing a file called build.sbt, what is this? and do i need it?
Edit:
If I press 'continue' on the picture above, I get
sbt:scalaproj>
Which looks fine, but if i type some code, like this:
sbt:scalaproj> var a : Int = 12;
Then it returns errors:
[error] Expected ';'
[error] var a : Int = 12
What in the world is going wrong? can someone point me to a guide for writing Scala in the prompt that is not too old to work?
Let's first understand the terminology. Scala is the language you are writing. SBT is an acronym for Scala Build Tool. Both of them have REPL.
When you call sbt in the command line, you initiate the REPL of sbt. The commands you can run there, are all commands sbt supports. You can find here the common commands. For example, if you run compile, it will compile the build.sbt located at the directory where you called the sbt command. Anyway, Scala commands WILL NOT work here. Scala commands are not sbt commands.
In order to run Scala REPL, you need to type console in the sbt REPL. You can find here the Scala REPL documentation. Within the Scala REPL you can run Scala commands.
P.S.
You can find the Scala download page here.

Installing IntelliJ + Scala under Ubuntu

I am a bit confused right now. I have installed IntelliJ and the Scala SDK using the installation wizard provided by IntelliJ. I selected the latest version 2.11.8 but were not able to run it in the terminal.
After that I ran
sudo apt-get install scala
which is apparently version 2.9.2
scala -version
Scala code runner version 2.9.2 -- Copyright 2002-2011, LAMP/EPFL
It appears that I now have installed scala under
/home/<user>/.ivy2/cache
(which comes from IntelliJ and has version 2.11.8) and also
whereis scala
scala: /usr/bin/scala /usr/bin/X11/scala /usr/share/man/man1/scala.1.gz
which comes from the package manager and hast version 2.9.2.
How would I clean up this mess?
This is not really a mess. It's perfectly possible to install a system-wide Scala and one based on your projects. The system-wide one really makes little sense except for you to run shell scripts using scala script.scala. You can also see that those Debian and Ubuntu packages are horribly outdated.
Since Scala is not an end-user application but a compiler or library required by specific project builds, one usually does not need and/or use a global installation. When you build a project using sbt or IntelliJ, your project can freely choose the Scala version it wants to use, whether that's 2.9.2, 2.10.x, 2.11.x or 2.12.0-Milestone... And therefore, these installations are all kept concurrently in a cache such as the Ivy cache you are seeing from IntelliJ/sbt.
$ ls -la ~/.ivy2/cache/org.scala-lang/scala-compiler/jars/
... scala-compiler-2.10.0.jar
... scala-compiler-2.10.2.jar
... scala-compiler-2.10.3.jar
... scala-compiler-2.10.4.jar
... scala-compiler-2.10.5.jar
... scala-compiler-2.10.6.jar
... scala-compiler-2.11.0.jar
... scala-compiler-2.11.1.jar
... scala-compiler-2.11.2.jar
... scala-compiler-2.11.5.jar
... scala-compiler-2.11.6.jar
... scala-compiler-2.11.7.jar
... scala-compiler-2.11.8.jar
... scala-compiler-2.12.0-M2.jar
... scala-compiler-2.12.0-M3.jar
... scala-compiler-2.7.3.jar
... scala-compiler-2.8.0.jar
... scala-compiler-2.8.2.jar
... scala-compiler-2.9.0.jar
... scala-compiler-2.9.2.jar
If you want a global installation because you want to run scripts without setting up a minimal sbt project, I recommend not to use apt (you can uninstall scala again) but simply download the latest version from http://scala-lang.org/download/ - I'm not aware of any .deb package depending on a .deb Scala installation.

Run Spark in standalone mode with Scala 2.11?

I follow the instructions to build Spark with Scala 2.11:
mvn -Dscala-2.11 -DskipTests clean package
Then I launch per instructions:
./sbin/start-master.sh
It fails with two lines in the log file:
Failed to find Spark assembly in /etc/spark-1.2.1/assembly/target/scala-2.10
You need to build Spark before running this program.
Obviously, it's looking for a scala-2.10 build, but I did a scala-2.11 build. I tried the obvious -Dscala-2.11 flag, but that didn't change anything. The docs don't mention anything about how to run in standalone mode with scala 2.11.
Thanks in advance!
Before building you must run the script under:
dev/change-version-to-2.11.sh
Which should replace references to 2.10 with 2.11.
Note that this will not necessarily work as intended with non-GNU sed (e.g. OS X)