How to get started with Scala?

Tomasz Godzik VirtusLab

Who am I

Lead of Scala CLI and Metals team

previously

contributor for Scala Center

What did I work on?

  • Mdoc
  • Metals
  • Scalameta
  • Dotty (a bit)
  • Bloop
  • various commercial projects

What did I work on?

  • Mdoc
  • Metals
  • Scalameta
  • Dotty (a bit)
  • Bloop
  • various commercial projects

We provide expert software engineering & consultancy services to give our clients a competitive edge​

Scala Space

Out brand new initiative to focus on technical aspects of the work done by SoftwareMill and VirtusLab

 

https://twitter.com/ScalaSpace

Agenda

1. How to install Scala?

2. How to write Scala?

3. How to compile Scala?

4. How to run Scala or test it?

5. How and which libraries do I get?

6. How to fix errors?

7. How to refactor Scala code?

Experiment

After each question will come a Q&A section.

 

Go to slido.com and enter 3001 code

 

Please post any issues that come to mind when thinking about a particular topic. I will try to answer at least one question after each section.

Why should we care about getting started?

Beginners

Newcomers

Every other developer

Maturity of the tooling and the community

How to install Scala?

One of the most basic questions

One of the most basic questions

 

but for a long time no obvious answer

Basic "scala" launcher

 

Everything else would need a build tool

Use a build tool, it's obvious!

 

 

Use a build tool, it's obvious?

 

 

Use a build tool, it's obvious?

 

 

Mill

You would also need Java

but...

 

wich one? how to get it?

"coursier setup" to the rescue!

"coursier setup" to the rescue!

  • sbt
  • sbtn
  • scala
  • scalac
  • Java
  • ammonite
  • scala-cli
  • scalafmt

"coursier setup" to the rescue!

But why do we need another package manager?

No matter the build tool, you would need to learn the language and the build tool

Scala CLI

The new oficial scala runner

 

Soon in all the best package managers!

Scala CLI

> brew install virtuslab/scala-experimental/scala

OR

> cs setup

> cs install scala-experimental 

Scala CLI

 

 

 

All the needed functionalities right from the start

./hello.scala
@main
def hello = println(“Hello Scala CLI!”)
> scala hello.scala
Hello Scala CLI!

Scala CLI

Known issues

 

  • package managers not yet updated, this might take a while

  • on scala-lang we'll get two ways of installing, via coursier and or via scala package

  • Scala CLI is directed towards small projects or scripts, so users still need to figure out a build tool

How to write Scala?

 Scala IDE

A bit of history

Intellij Idea

Ensime

 Scala IDE

A bit of history

Intellij Idea

Ensime

LSP + Metals

Protocol that defines the exchanges between client and the server to provide IDE features for a programming language

Language server protocol

  • uses JSON RPC

  • backed by Microsoft used by open source

  • abstracts language support from UI

  • well defined and supported in multiple editors

Language server protocol

Makes it easy to focus on making sure that the language is supported and doesn’t require any knowledge of the editor.

Language server protocol

- you should not need to learn a new editor for a new language

- "just use Intellij" is not an answer (unless you are used to that)

- tooling is important for the language, but language should not be just the IDE

Language server protocol

So how to write Scala?

Depends!

So how to write Scala?

Metals or Intellij?

 

Just try it out!

 

You can ask around your team or the community for pointers.

Beginners

 

Stick with whatever editor you are used to.

 

You should have a choice to do that.

New to the language

 

Your machine is older?

You want a ready workspace?

You don't want to set up the environment?

 

Metals via Gitpod or Github Codespaces

Alternative: Online IDEs

Intellij Idea

Metals

scalameta.org/metals

 

Current issues

  • we need more guides on setting up  

  • making single file work for users, maybe with default Scala CLI

  • Metals stability issues

  • Intellij support issues for Scala 3 (highly encourage people to report any issues and use the nightly)

  • no exploration of environment setup for and blessed way of doing things

 

How to compile Scala?

- obviously done by the compiler

- but how do we actually interact with the compiler while writing code?

- no one really wants to invoke the compiler manually each time

 

Compilation

  • built-in compiler server
  • Build Server Protocol

Compilation

  • Build Server Protocol
  • built-in compiler server
  • Build Server Protocol

Compilation

  • Build Server Protocol
  • similar to LSP, solves a similar problem.
  • created along with Bloop
  • clients can interact directly with the build tool.
  • no need for additional export for specific IDE
  • helps to reduce the barrier between CLI and the editor

Build server protocol

How does it work?

BSP Server

LSP Server

LSP Server

(e.g. Metals)

Editor

(e.g. VS Code)

BSP Server

(e.g. Bloop)

completions

hover

refrences

...

compile

test

run

...

Why is BSP important for Scala?

sbt

mill

Bazel

Maven

Gradle

Bleep

...

BSP Implementations

  • Bloop - build server

  • sbt - works as single server, for a single project

  • mill - same as sbt

  • Bazel BSP

  • Scala CLI

  • Bleep

What provides the best getting started experience?

Which one to use?

  • single file or a script -> Scala CLI
  • complex mill/sbt project -> dedicated server
  • multiple smaller projects or simpler definition -> export to Bloop
  • huge project -> use Bazel with BSP

Which one to use?

 

Current issues

  • maturity of some BSP servers still needs more work

  • sbt BSP limited to one task being executed

  • stability issues

  • Bloop most mature and useful general purpose dire need of refactoring

  • Bloop has a fork :(

  • Still ongoing work for Bazel BSP

How to run or test Scala?

> cat main.scala
@main def hello() = println("Hello world!")
> scala run main.scala
Hello world!
> cat main2.sc
println("Hello world!")
> scala run main.sc
Hello world!

Run via command line

> scala run --js main.sc
Downloading Scala.js CLI
Downloading 2 dependencies
Compiling project (Scala 3.3.0, Scala.js)
Compiled project (Scala 3.3.0, Scala.js)
Hello world!

Chose your platform

> scala run --native .
Compiling project (Scala 3.3.0, Scala Native)
Compiled project (Scala 3.3.0, Scala Native)
[info] Linking (1680 ms)
[info] Discovered 683 classes and 3779 methods
[info] Optimizing (debug mode) (1523 ms)
[info] Generating intermediate code (1300 ms)
[info] Produced 8 files
[info] Compiling to native code (2692 ms)
[info] Total (7465 ms)
Hello world!

Chose your platform

> scala-cli . --debug --debug-mode attach --debug-port 5004 
Listening for transport dt_socket at address: 5004

Even debug!

Not only run, but also test!

//> using test.dep org.scalameta::munit::1.0.0-M7

class MyTests extends munit.FunSuite {
 test("foo") {
   assert(2 + 2 == 4)
 }
}
> scala test .
Compiling project (Scala 3.3.0, JVM)
Compiled project (Scala 3.3.0, JVM)
Compiling project (test, Scala 3.3.0, JVM)
Compiled project (test, Scala 3.3.0, JVM)
MyTests:
  + foo 0.01s

Using directives

Scala CLI allows for specifying anything you would on the commandline in special comments.

//> using scala 3.3.0
//> using platform native
//> using options -Wunused -Wvalue-discard

I highly recommend taking a look at the documentation of Scala CLI as it mentions all the possibilities

 

https://scala-cli.virtuslab.org/docs/commands/run.

But what about the IDE ???

 

Both Metals and Intellij support run and debug!

 

And Scala CLI!

 

Run in Metals

 

Couple of different ways of running.

Code lenses - run

 

Code lenses - debug

 

Code lenses - debug

 

Uses scala debug adapter library and DAP protocol to provide debugging support in all editors that implement it.

Code lenses - native/js

 

Test explorer (VS Code)

 

Known problems

 

  • Tests in Metals could be quicker.

  • Regression in script support for Scala CLI 1.0.0 (fixed in 1.0.1)

  • debugging always a complex topic, but more improvements are coming

How and which Scala libraries to get?

  • coursier resolve _

  • Metals reuse that mechanism for Ammonite, Worksheet, Scala CLI and sbt completions.

  • Intellij will have suggestions, but this is a bit limited

  • There is an additional plugin for VS Code that uses the Scaladex API

  • manually via Scaladex

If you know the coordinates (or partly)

Is the question!

But which?

Scala toolkit to the rescue

//> using toolkit latest

class MyTests extends munit.FunSuite {
 test("foo") {
   assert(2 + 2 == 4)
 }
}

There's more!

//> using toolkit typelevel:latest

import cats.effect.*
import fs2.io.file.Files

object Hello extends IOApp.Simple {
 def run = Files[IO].currentWorkingDirectory.flatMap { cwd =>
   IO.println(cwd.toString)
 }
}

Advantages

 

- accessibility of the language

- ready pathways to follow

- standardizes on approaches

- gives you the right tools for the task

Current issues

  • cross version suffix

  • toolkit still in early phases, we need to add more libraries!

  • coordinates are quite long `org:name:version`

  • directives in the comment seem easy to break despite being very useful

  • no automatic completion of the directives, one must know about them

Bonus question:

How to work within corporate environments?

Good getting started experience in corporate environments is important for language adoption

  • set additional corporate repositories to download Metals artifacts from

  • coursier mirror if it’s not possible to download from Maven central directly

  • setting up proxies for both Metals and Bloop to be done in user settings

Metals?

How can we do better?

How to fix errors?

Errors are a way of communicating with the user, one of the first thing they will see.

Clear errors are important

Each error in Scala 3 has a code

Explain option


class A

val i: Int = A()

Explain option

> scala compile .
Compiling project (Scala 3.3.0, JVM)
[error] ./main.scala:5:14
[error] Found:    A
[error] Required: Int
[error] val i: Int = A()
[error]              ^^^
Error compiling project (Scala 3.3.0, JVM)
Compilation failed

Explain option

-- [E007] Type Mismatch Error: /home/tgodzik/Documents/workspaces/sample-scala-cli-project/main.scala:6:14 
6 |val i: Int = A()
  |             ^^^
  |             Found:    A
  |             Required: Int
  |-----------------------------------------------------------------------------
  | Explanation (enabled by `-explain`)
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  |
  | Tree: new A()
  | I tried to show that
  |   A
  | conforms to
  |   Int
  | but the comparison trace ended with `false`:
  |
  |   ==> A  <:  Int
  |   <== A  <:  Int = false
  |
  | The tests were made under the empty constraint
   -----------------------------------------------------------------------------
1 error found
Compilation failed

But we can do better!

Actionable diagnostics

Compiler or build tools know how to fix their stuff (most of the time)

 

 We can propagate automatic fixes suggestions form the compiler to the IDEs

 

This gives us errors with ready fixes for the user to try

Actionable diagnostics

Known issues

 

  • there is still plenty of work to do on making the compiler messages clearer

  • –explain option requires rerunning the compilation and doesn't work with Bloop

  • the actionable diagnostic journey has only begun, there is plenty of work to be done

How to refactor Scala code?

Refactoring

Automatic changes to the code driven by the IDE

 

Expected by more advanced users especially when coming from other languages

 

Affects the maintainability of the software we create

Refactorings

Well known for large amount of refactorings (aside maybe from Scala 3 issues)

Still catching up and might never fully provide the same capabilities

Metals refactorings

  • rename
  • move file
  • extract method
  • inline value
  • convert to for comprehension
  • organize imports
  • add type
  • more!

Scalafix?

  • Scalafix is a well know tool with custom rules for linting and rewrites
  • Can be used from Metals, but the integration is not yet full
  • Organize imports and run Scalafix rules
  • No linting

Better integration with Scalafix

  • Add linting
  • Easier configuration for custom rules
  • Quick fixes within linting rules
  • Essentially a plugin infra for Metals
  • Bonus: It all can be run on CI and reused in Intellij

Known issues

  • Scalafix needs more work with the API and Scala 3 support

  • custom rules need to be added by hand to metals configuration

  • refactorings in Metals are an ongoing work and it’s quite hard to handle all the edge cases especially in a language like Scala

More questions?

 

Social media:

Twitter @TomekGodzik,

Mastodon https://fosstodon.org/@tgodzik  

 

Contact as at VirtusLab: tgodzik@virtuslab.com

Copy of How to get started with Scala?

By Tomek Godzik

Copy of How to get started with Scala?

  • 45