I was looking to improve by bash-skills and came across exercism.org, which has exercises in a veritable plethora of different languages. The emphasis seems to be on mentoring, but when I tried that I never got any response, which I didn’t find particularly surprising: why anyone would want to review other people’s crappy solutions to simple bash exercises for free is beyond me.
However it comes with a CLI and you can just try out any of the exercises in your local environment, with test scripts included. Then you can upload it back to the site, and even if you’ve got it hopelessly wrong, you can view community solutions and hopefully learn a thing or two about how to do it right.
The site just in the past couple of weeks went through a major upgrade, and theoretically allows you to do the problems and run tests right there in your own flipping browser, though it wasn’t yet working for Scala. I’m sure it will work at some point, but I don’t think it’ll be as nice to develop in as an IDE, with intelligent code completion and instant syntax and type checking.
They have nearly 100 Scala exercises with Scalatest tests, which are mostly pretty easy, but good for keeping the old skillz sharp. After doing a few I saw someone had submitted a solution in Scala 3.
Scala 3!?! Ah, so Dotty is finally on general release. After reading up a bit on the new bits and pieces (reduced need for curly braces, and significant indentation being the most obvious differences, with the implicit
keyword being given the boot in most circumstances, in close second), I decided to give it a go.
So I’m just sharing some practical tips on how to get it working.
First, build.sbt
needs to be updated to tell sbt that you want it to run Scala 3. So change the scalaVersion
to 3.0.1 as of the time or writing.
Also, the version of Scalatest needs updating to work with Scala 3, currently 3.2.9
Then, it turns out that Scalatest in their wisdom recently decided to change the name of FunSuite
to AnyFunSuite
and switch all the packages around, so the test source imports and class names need updating.
Finally, if you’ve tried importing the project as a module into IntelliJ already, you’ll have a build.properties
file that may specify an old version of sbt. It seems you need at least version 1.5.x in order to compile Scala 3 code, so in that case you’ll need to update the `sbt.version` specified there (1.5.5 is currently latest). In theory you can set the sbt version used from “Bundled” to a “Custom” version in IntelliJ Settings, but I found it kept switching back to “Bundled”.
So I put together a little bash script to do all this for me, which I then assigned to an alias “cs3” (Convert to Scala 3), and can run in the downloaded directory. The replacements may not be exhaustive, but work with most exercises. A few exercises come with other weird dependencies in the build.sbt file that you might need to update manually or comment out.
Here it is. Feel free to copy/paste it and use.
#!/usr/bin/env bash # Check we're in a valid directory if [[ $PWD =~ xercism/scala/.+ ]] ; then echo "directory OK" else echo "invalid directory"; exit 1 fi # build.sbt: Replace scala and scalatest versions perl -i -0pe 's/scalaVersion :=.*/scalaVersion := "3.0.1"/' build.sbt perl -i -0pe 's/"scalatest" % "[^"]*"/"scalatest" % "3.2.9"/' build.sbt # build.properties (if supplied): Replace sbt version if [[ -a project/build.properties ]] ; then perl -i -0pe 's/sbt\.version=.*/sbt.version=1.5.5/' project/build.properties echo build.properties updated fi # test source: Change scalatest imports filename=$(find src/test/scala/*.scala |head -1) ## FunSuite perl -i -0pe 's/import org.scalatest.{Matchers, FunSuite}/import org.scalatest.funsuite.AnyFunSuite\nimport org.scalatest.matchers.should.Matchers/' "$filename" perl -i -0pe 's/import org.scalatest.{FunSuite, Matchers}/import org.scalatest.funsuite.AnyFunSuite\nimport org.scalatest.matchers.should.Matchers/' "$filename" perl -i -0pe 's/extends FunSuite/extends AnyFunSuite/' "$filename" ## FlatSpec perl -i -0pe 's/import org.scalatest.{Matchers, FlatSpec}/import org.scalatest.flatspec.AnyFlatSpec\nimport org.scalatest.matchers.should.Matchers/' "$filename" perl -i -0pe 's/extends FlatSpec/extends AnyFlatSpec/' "$filename"
I also made a handy script to submit the build.sbt and test files along with the solution source file, so that people on Exercism can see the changes required to run it. I aliased this to “exs” (“Exercism submit”).
#!/usr/bin/env bash if [[ $PWD =~ xercism/scala/.+ ]] ; then echo "directory OK" else echo "invalid directory"; exit 1 fi files="$(ls -d ./src/main/scala/* build.sbt ./src/test/scala/* | xargs)" echo "files: $files" exercism submit $files
Just paste these into files, and add an alias in ~/.bash_aliases
, something like
alias exs="/mnt/c/Users/rjone/Exercism/scala/submitScala3.bash" alias cs3="/mnt/c/Users/rjone/Exercism/scala/convertToScala3.bash"
So my workflow is this:
- Open my Exercism project in IntelliJ, where I have directories for bash, scala etc.
- If I’m using Windows, switch to WSL2 bash by typing “bash” in the terminal
- Download an exercise by copy-pasting the command provided on the exercise page
- cd to the
scala/whatever-exercise
folder - Run
cs3
- Fire up
sbt
(make sure you have version 1.5.x + on your command line), which will add the build properties - If I want syntax checking, highlighting etc, click the “+” button (Link sbt Project) in the sbt Tool Window, and select the exercise folder. This will allow IntellJ to know your Scala version and to import and index your libraries.
- Do some coding
- Test using sbt test in the terminal. If you’ve done step 7, you can use IntellJ’s runner, though it had problems not running pending tests if they weren’t implemented yet (which you can get around by replacing ??? with null) – and frankly the terminal is faster and easier
- Submit using
exs
One other IntelliJ quirk I found was that I couldn’t get the sbt tool window to appear to allow me to import a project folder: it simply wasn’t there in the tool windows menu. I think I had to go into Project Structure and make a new Scala module first as a one-off to make the tool window appear – but my mind has gone a bit hazy around this.
To be honest, though, it’s a lot simpler than it sounds!
And Scala 3 is great. Compilation is still slow, but I’m loving the new syntax.