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
Come to our booth!
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
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 (soon fixed)
-
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
How to get started with Scala?
By Tomek Godzik
How to get started with Scala?
- 375