Scala runs...

  • on the JVM
  • on JavaScript in your browser
  • natively with LLVM beta

Scala in a Nutshell

click the boxes below to see Scala in action!

Seamless Java Interop

Scala runs on the JVM, so Java and Scala stacks can be freely mixed for totally seamless integration.

Type Inference

So the type system doesn’t feel so static. Don’t work for the type system. Let the type system work for you!

Concurrency & Distribution

Use data-parallel operations on collections, use actors for concurrency and distribution, or futures for asynchronous programming.

class Author(val firstName: String,
    val lastName: String) extends Comparable[Author] {

  override def compareTo(that: Author) = {
    val lastNameComp = this.lastName compareTo that.lastName
    if (lastNameComp != 0) lastNameComp
    else this.firstName compareTo that.firstName

object Author {
  def loadAuthorsFromFile(file: List[Author] = ???
import static scala.collection.JavaConversions.asJavaCollection;

public class App {
    public List<Author> loadAuthorsFromFile(File file) {
        return new ArrayList<Author>(asJavaCollection(

    public void sortAuthors(List<Author> authors) {

    public void displaySortedAuthors(File file) {
        List<Author> authors = loadAuthorsFromFile(file);
        for (Author author : authors) {
                author.lastName() + ", " + author.firstName());

Combine Scala and Java seamlessly

Scala classes are ultimately JVM classes. You can create Java objects, call their methods and inherit from Java classes transparently from Scala. Similarly, Java code can reference Scala classes and objects.

In this example, the Scala class Author implements the Java interface Comparable<T> and works with Java Files. The Java code uses a method from the companion object Author, and accesses fields of the Author class. It also uses JavaConversions to convert between Scala collections and Java collections.

Type inference
scala> class Person(val name: String, val age: Int) {
     |   override def toString = s"$name ($age)"
     | }
defined class Person

scala> def underagePeopleNames(persons: List[Person]) = {
     |   for (person <- persons; if person.age < 18)
     |     yield
     | }
underagePeopleNames: (persons: List[Person])List[String]

scala> def createRandomPeople() = {
     |   val names = List("Alice", "Bob", "Carol",
     |       "Dave", "Eve", "Frank")
     |   for (name <- names) yield {
     |     val age = (Random.nextGaussian()*8 + 20).toInt
     |     new Person(name, age)
     |   }
     | }
createRandomPeople: ()List[Person]

scala> val people = createRandomPeople()
people: List[Person] = List(Alice (16), Bob (16), Carol (19), Dave (18), Eve (26), Frank (11))

scala> underagePeopleNames(people)
res1: List[String] = List(Alice, Bob, Frank)

Let the compiler figure out the types for you

The Scala compiler is smart about static types. Most of the time, you need not tell it the types of your variables. Instead, its powerful type inference will figure them out for you.

In this interactive REPL session (Read-Eval-Print-Loop), we define a class and two functions. You can observe that the compiler infers the result types of the functions automatically, as well as all the intermediate values.

val x = Future { someExpensiveComputation() }
val y = Future { someOtherExpensiveComputation() }
val z = for (a <- x; b <- y) yield a*b
for (c <- z) println("Result: " + c)
println("Meanwhile, the main thread goes on!")

Go Concurrent or Distributed with Futures & Promises

In Scala, futures and promises can be used to process data asynchronously, making it easier to parallelize or even distribute your application.

In this example, the Future{} construct evaluates its argument asynchronously, and returns a handle to the asynchronous result as a Future[Int]. For-comprehensions can be used to register new callbacks (to post new things to do) when the future is completed, i.e., when the computation is finished. And since all this is executed asynchronously, without blocking, the main program thread can continue doing other work in the meantime.


Combine the flexibility of Java-style interfaces with the power of classes. Think principled multiple-inheritance.

Pattern Matching

Think “switch” on steroids. Match against class hierarchies, sequences, and more.

Higher-order functions

Functions are first-class objects. Compose them with guaranteed type safety. Use them anywhere, pass them to anything.

abstract class Spacecraft {
  def engage(): Unit
trait CommandoBridge extends Spacecraft {
  def engage(): Unit = {
    for (_ <- 1 to 3)
  def speedUp(): Unit
trait PulseEngine extends Spacecraft {
  val maxPulse: Int
  var currentPulse: Int = 0
  def speedUp(): Unit = {
    if (currentPulse < maxPulse)
      currentPulse += 1
class StarCruiser extends Spacecraft
                     with CommandoBridge
                     with PulseEngine {
  val maxPulse = 200

Flexibly Combine Interface & Behavior

In Scala, multiple traits can be mixed into a class to combine their interface and their behavior.

Here, a StarCruiser is a Spacecraft with a CommandoBridge that knows how to engage the ship (provided a means to speed up) and a PulseEngine that specifies how to speed up.

Switch on the structure of your data

In Scala, case classes are used to represent structural data types. They implicitly equip the class with meaningful toString, equals and hashCode methods, as well as the ability to be deconstructed with pattern matching.

In this example, we define a small set of case classes that represent binary trees of integers (the generic version is omitted for simplicity here). In inOrder, the match construct chooses the right branch, depending on the type of t, and at the same time deconstructs the arguments of a Node.

Pattern matching
// Define a set of case classes for representing binary trees.
sealed abstract class Tree
case class Node(elem: Int, left: Tree, right: Tree) extends Tree
case object Leaf extends Tree

// Return the in-order traversal sequence of a given tree.
def inOrder(t: Tree): List[Int] = t match {
  case Node(e, l, r) => inOrder(l) ::: List(e) ::: inOrder(r)
  case Leaf          => List()

Go Functional with Higher-Order Functions

In Scala, functions are values, and can be defined as anonymous functions with a concise syntax.

val people: Array[Person]

// Partition `people` into two arrays `minors` and `adults`.
// Use the anonymous function `(_.age < 18)` as a predicate for partitioning.
val (minors, adults) = people partition (_.age < 18)
List<Person> people;

List<Person> minors = new ArrayList<Person>(people.size());
List<Person> adults = new ArrayList<Person>(people.size());
for (Person person : people) {
    if (person.getAge() < 18)

Run Scala in your browser

Scastie is Scala + sbt in your browser! You can use any version of Scala, or even alternate backends such as Dotty, Scala.js, Scala Native, and Typelevel Scala. You can use any published library. You can save and share Scala programs/builds with anybody.

Run Scala code interactively

Online Courses

Functional Programming Principles in Scala

  • Free (optional paid certificate)
  • New sessions starting every 2 weeks!

Functional Program Design in Scala

  • Free (optional paid certificate)
  • New sessions starting every 2 weeks!

Parallel Programming

  • Free (optional paid certificate)
  • New sessions starting every 2 weeks!

Big Data Analysis with Scala and Spark

  • Free (optional paid certificate)
  • New sessions starting every 2 weeks!

Functional Programming in Scala Capstone

  • Free (optional paid certificate)
  • New sessions starting every 2 weeks!

Effective Programming in Scala

  • Free (optional paid certificate)
  • New sessions starting every 2 weeks!

Programming Reactive Systems

  • Free (optional paid certificate)
  • New sessions starting every 2 weeks!

Upcoming Training

Scala ecosystem

The Scala Library Index (or Scaladex) is a representation of a map of all published Scala libraries. With Scaladex, a developer can now query more than 175,000 releases of Scala libraries. Scaladex is officially supported by Scala Center.

The Scala Library Index

What’s New


Scala 3.0.1 and 3.0.2-RC1 are here!

Wednesday, July 21, 2021

Greetings from the Scala 3 team! We are glad to announce that Scala 3.0.1 and 3.0.2-RC1 are now officially out.

As no critical bugs have been found in the previously released Scala 3.0.1-RC2, it has been promoted to 3.0.1. It is the first stable release after 3.0.0 and it incorporates the changes described in detail in the articles for its pre-releases: 3.0.1-RC1 and 3.0.1-RC2. The unified changelog can be found here.

Scala 3.0.2-RC1, in turn, incorporates new language improvements and bug fixes described below.

You can expect the release of stable 3.0.2 and a release candidate for a the next version in 6 weeks from now (1st September).

Improved insertion of semicolons in logical conditions

Scala 3’s indentation based syntax is aimed at making your code more concise and readable. As it gets broader adoption, we consistently improve its specification to eliminate corner cases which might lead to ambiguities or counterintuitive behaviours.

Thanks to #12801 it is now allowed for a logical expression in an if statement or expression to continue in the following line if it starts in the same line as the if keyword, e.g.

if foo
then //...

can now be used instead of

if foo(bar)
then //...

If your intention is to have a block of code evaluating into a single condition you should add a new line and indentation directly after if, e.g.

  val cond = foo(bar)
then //...

so code like below would NOT be valid

if val cond = foo(bar)
then //...

Towards better null safety in the type system

The compiler option -Yexplicit-nulls modifies Scala’s standard type hierarchy to allow easier tracing of nullable values by performing strict checks directly on the level of the type system rather than just relying on conventions (e.g. this prevents you from writing code like val foo: Option[String] = Some(null), which would be otherwise valid Scala although very likely to cause a NullPointerException at some further point).

After the recently introduced changes with this option enabled the Null type becomes a subtype of Matchable instead of inheriting directly from Any, making the code below compile (this used to compile before only without strict nullability checking).

def foo[T <: Matchable](t: T) = t match { case null => () }

Method search by type signature

You can now browse the documentation of Scala’s API not only by names of methods but also by their type in a Hoogle-like manner (but with Scala syntax) thanks to integration with Inkuire brought up by #12375.

To find methods with the desired signature simply write in scaladoc’s searchbar the type you would expect them to have after eta-expansion (as if they were functions rather than methods).

image url "image Title"

Typing escape hatch for structural types

Structural types may come in handy in many situations, e.g. when one wants to achieve a compromise between safety of static typing and ease of use when dealing with dynamically changing schemas of domain data structures. They have however some limitations. Among others structural typing doesn’t normally play well with method overloading because some types of reflective dispatch algorithms (inlcuding JVM reflection) might not be able to choose the overloaded method alternative with the right signature without knowing upfront the exact types of the parameters after erasure. Consider the following snippet.

class Sink[A] { def put(x: A): Unit = {} }
val a = Sink[String]()
val b: { def put(x: String): Unit } = a

This code won’t compile. This is because when Sink[String] gets erased to Sink[Object] (as it’s seen from JVM’s perspective) the method’s signature becomes put(x: Object): Unit while for the structural type it remains unchanged as put(x: String): Unit and they wouldn’t match in runtime therefore Sink[String] cannot be treated as a subtype of { def put(x: String): Unit }.

We might however try to write a better method dispatch algorithm ourselves instead of relying on the JVM’s default one to make this work. To assure the compiler that we know what we’re doing we’ll need to use the new Selectable.WithoutPreciseParameterTypes marker trait. Currently it’s an experimental feature (introduced by #12268) so you’ll be able to use it only with a snapshot or nightly version of the compiler and you’ll need to annotate all subtypes of this trait with @experimental.

import annotation.experimental

@experimental trait MultiMethodSelectable extends Selectable.WithoutPreciseParameterTypes:
  // smartly choose the right method implementation to call
  def applyDynamic(name: String, paramTypes: Class[_]*)(args: Any*): Any = ???

@experimental class Sink[A] extends MultiMethodSelectable:
  def put(x: A): Unit = {}

val a = new Sink[String]
val b: MultiMethodSelectable { def put(x: String): Unit } = a

This snippet will compile as the compiler won’t perform the precise signature check for b anymore.

More details


Keeping in mind how important metaprogramming has become to Scala developers (especially creators of libraries) we continue to make it more reliable by fixing reported bugs and more powerful by repealing formerly introduced limitations. If you’re curious how it was done look at the PRs below:

  • Map opaque types in arguments of inlined calls to proxies #12922
  • Don’t forget side effects in prefixes of inlined function calls #12842
  • Drop “no inlines with opaques” implementation restriction #12815
  • Detect abstract inline method calls after inlining #12777
  • Fix implicit ValueOf synthesis #12615

Other notable improvements

  • Add Scala 3 batch commands for Windows #13006
  • Fix #12981: show diagnostics levels (warn | error) in REPL #13000
  • Add no links warning setting to scaladoc #12936
  • Use WeakHashSet instead of HashSet for hash-consing types #12935
  • Balance And/Or types when forming lubs and glbs #12928
  • Restricts isInstanceOf[Null] checks #12905
  • Add support for shallow capture sets #12875
  • Drop implementation restriction for polymorphic functions #12863
  • Preserve hard unions in more situations #12654
  • Better support type-heavy pattern matches #12549

Other notable bug fixes

  • Fix #13046: override is a valid identifier in Java, not a keyword #13048
  • Don’t emit Java generic signatures for constructors #13047
  • Exhaustivity warnings on nested case classes #13030
  • Refine overriding pairs in RefChecks #12982
  • Let annotations on parameters see preceding type parameters #12980
  • Retain transparent flag on exports #12978
  • Widen unions before finding members #12925
  • ProtoTypes#normalizedCompatible: keep more constraints #12924
  • Detect provisional superclasses and recompute them in Typer #12912
  • Properly handle self-types in reflection member lookup #12893
  • Use Java rules for member lookup in .java sources #12884
  • Hide problematic static forwarders #12860
  • When checking tp1 <:< tycon2[args2], widen tp1 to reveal application #12846
  • Skip contexts for implicit search when resolving imports #12816
  • Insert conversions also on selections wrapped in type applications #12719
  • Emit generic signature for static forwarders to nullary methods #12710
  • Add Matchable to the parents of Null in explicit nulls #12697
  • Always generate a partial function from a lambda #12670
  • Fix #12572: Ignore default accessor bridges in non-native JS classes. #12657


Thank you to all the contributors who made this release possible 🎉

According to git shortlog -sn --no-merges 3.0.1-RC2..3.0.2-RC1 these are:

    85	Martin Odersky
    60	Liu Fengyun
    47	Kacper Korban
    28	Filip Zybała
    17	Andrzej Ratajczak
    16	Guillaume Martres
    15	Jamie Thompson
    10	bjornregnell
     9	tanishiking
     8	Dylan Halperin
     8	Anatolii Kmetiuk
     7	Tom Grigg
     5	Som Snytt
     5	changvvb
     4	Nicolas Stucki
     4	Aleksander Boruch-Gruszecki
     4	Sébastien Doeraene
     4	Michał Pałka
     3	Magnolia.K
     3	Phil
     3	Krzysztof Romanowski
     3	Paweł Marks
     2	xuwei-k
     2	Ben Plommer
     2	Florian Schmaus
     2	Lukas Rytz
     2	Maciej Gorywoda
     2	Markus Sutter
     2	Roman Kotelnikov
     2	Stéphane Micheloud
     2	noti0na1
     2	vincenzobaz
     1	Ondrej Lhotak
     1	KazuyaMiayshita
     1	odersky
     1	Julian Mendez
     1	Anton Sviridov
     1	GavinRay97
     1	EnzeXing
     1	Tomas Mikula
     1	Tomasz Godzik
     1	Vaastav Arora
     1	Vadim Chelyshov
     1	Will Sargent
     1	Zofia Bartyzel
     1	Dale Wijnand
     1	Bjorn Regnell
     1	dmitrii.naumenko
     1	Adrien Piquerez
     1	Meriam Lachkar
     1	Martin
     1	Olivier Blanvillain
     1	Lorenzo Gabriele

Library authors: Join our community build

Scala 3 now has a set of widely-used community libraries that are built against every nightly Scala 3 snapshot. Join our community build to make sure that our regression suite includes your library.

Twitter Feed

See more tweets, or

Follow Scala on twitter

The Scala language is maintained by

  • Scala Center
  • Lightbend
  • VirtusLab

Scala Center is supported by

EPFL Goldman Sachs 47 Degrees Twitter Spotify Lunatech Your company