Object-Oriented Meets Functional

Have the best of both worlds. Construct elegant class hierarchies for maximum code reuse and extensibility, implement their behavior using higher-order functions. Or anything in-between.

Learn More

 

Scala began life in 2003, created by Martin Odersky and his research group at EPFL, next to Lake Geneva and the Alps, in Lausanne, Switzerland. Scala has since grown into a mature open source programming language, used by hundreds of thousands of developers, and is developed and maintained by scores of people all over the world.
Download API Docs    
Spiral
Scala
2.11.7

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.

Traits

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.

Author.scala
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: java.io.File): List[Author] = ???
}
App.java
import static scala.collection.JavaConversions.asJavaCollection;

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

    public void sortAuthors(List<Author> authors) {
        Collections.sort(authors);
    }

    public void displaySortedAuthors(File file) {
        List<Author> authors = loadAuthorsFromFile(file);
        sortAuthors(authors);
        for (Author author : authors) {
            System.out.println(
                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 person.name
     | }
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.

Concurrent/Distributed
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.

Traits
abstract class Spacecraft {
  def engage(): Unit
}
trait CommandoBridge extends Spacecraft {
  def engage(): Unit = {
    for (_ <- 1 to 3)
      speedUp()
  }
  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.

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()
}

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.

Go Functional with Higher-Order Functions

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

Scala
val people: Array[Person]

// Partition `people` into two arrays `minors` and `adults`.
// Use the higher-order function `(_.age < 18)` as a predicate for partitioning.
val (minors, adults) = people partition (_.age < 18)
Java
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)
        minors.add(person);
    else
        adults.add(person);
}

In the Scala example on the left, the partition method, available on all collection types (including Array), returns two new collections of the same type. Elements from the original collection are partitioned according to a predicate, which is given as a lambda, i.e., an anonymous function. The _ stands for the parameter to the lambda, i.e., the element that is being tested. This particular lambda can also be written as (x => x.age < 18).

The same program is implemented in Java on the right.

Upcoming Events

See more events or add one to our feed

What's New

announcement
date icon Tuesday, July 14, 2015

We are pleased to announce the availability of Scala 2.12.0-M2!

We would like to highlight the following changes since M1:

  • Java 8 is now required.
  • Lambdas are compiled to Java 8 style closures.

Compared to M1, this release resolves 9 issues. We merged 29 pull requests.

As usual for milestones, 2.12.0-M2 is not binary compatible with any other Scala release, including other 2.12 milestones.

About Scala 2.12

Beginning with 2.12.0-M2, the Scala 2.12 series targets Java 8. Programs written in Scala 2.12, including the Scala 2.12 compiler, can only be executed on Java 8 or newer.

Source compatibility

Scala 2.12 is mostly source compatible with 2.11. Code that compiles on 2.11.x without deprecation warnings should compile on 2.12.x too, unless you use experimental APIs such as reflection. If you find incompatibilities, please file an issue.

Binary compatibility

Since Scala 2.11, minor releases of Scala are binary compatible with each other. Scala 2.12 will continue this tradition: every 2.12.x release will be binary compatible with 2.12.0. Milestone releases and release candidates, however, are not binary compatible with any other release.

Scala 2.12 is not and will not be binary compatible with the 2.11.x series. This allows us to keep improving the Scala compiler and standard library. We are working with the community to ensure that core projects in the Scala eco-system become available for 2.12. Please refer to this growing list of libraries and frameworks.

The Scala 2.11.1 release notes explain in more detail on how binary compatibility works in Scala. The same policies that applied to 2.11 will apply to 2.12 as well.

New features

Future 2.12 milestones will include additional new features. For now, M2 includes the following major changes:

New backend

Scala 2.12 enables the “GenBCode” backend by default.

The new backend is more efficient than the default backend of Scala 2.11, because it directly generates ASM bytecode from Scala compiler trees, while the previous backend used an intermediate representation called “ICode”.

Java 8 style closure classes

Scala 2.12 emits closures in the same style as Java 8.

For each lambda the compiler generates a method containing the lambda body. At runtime, this method is passed as an argument to the LambdaMetaFactory provided by the JDK, which creates a closure object.

Compared to Scala 2.11, the new scheme has the advantage that the compiler does not generate an anonymous class for each lambda anymore. This leads to significantly smaller JAR files.

Lambda syntax for SAM types (experimental)

As of M2, this feature is not yet on by default. You can enable it with the -Xexperimental compiler option.

When the option is enabled, then similar to Java 8, Scala 2.12 allows instantiating any type with one single abstract method by passing a lambda. This improves the experience of using libraries written for Java 8 in Scala.

This feature was also available in Scala 2.11, also via -Xexperimental.

New Bytecode Optimizer

The GenBCode backend includes a new inliner and bytecode optimizer. The optimizer is enabled using the -Yopt:l:classpath compiler option. Check -Yopt:help to see the full list of available options for the optimizer.

As of M2, the following optimizations are available:

  • Inlining final methods, including methods defined in objects and final methods defined in traits
  • If a closure is allocated and invoked within the same method, the closure invocation is replaced by an invocations of the corresponding lambda body method
  • Dead code elimination and a small number of cleanup optimizations

The work on the new optimizer is still ongoing. You can track it in the scala-opt repository issue tracker.

Unbundled features

The following modules have been removed from the Scala 2.12 distribution:

Contributors

A big thank you to everyone who’s helped improve Scala by reporting bugs, improving our documentation, spreading kindness in mailing lists and other public fora, and submitting and reviewing pull requests! You are all magnificent.

According to git shortlog -sn --no-merges 2.11.x..v2.12.0-M2, 40 people have contributed to Scala 2.12 so far: Lukas Rytz, Jason Zaugg, A. P. Marki, Rex Kerr, Adriaan Moors, Kato Kazuyoshi, Max Bileschi, Rui Gonçalves, jxcoder, François Garillot, rubyu, Dominik Gruntz, Evgeny Vereshchagin, Kenji Yoshida, Marc Siegel, Masato Sogame, Simon Ochsenreither, Todd Vierling, Viktor Klang, Maks Atygaev, dgruntz, harryhuk, Denton Cockburn, Paolo Giarrusso, Denis Rosset, Roman Hargrave, Antoine Gourlay, Seth Tisue, Shadaj, Alexey Romanov, Steven Scott, Tim Vergenz, martijnhoekstra, Aleksandar Prokopec, Janek Bogucki, Eugene Dzhurinsky, cchantep, Lukas Elmer, Erlend Hamnaberg, Malte Isberner. Thank you!

Thanks also to Miguel Garcia and James Iry for their substantial prior work on the new compiler backend.

Release notes

You can propose edits to these release notes on GitHub.

Obtaining Scala

Scala releases are available various ways, such as:

Recently...

date-icon Thursday, June 25, 2015 news
We are pleased to announce that the Phil Bagwell Memorial Scala Community Award for 2015 has been awarded to Bill Venners. The award was presented...
date-icon Tuesday, June 23, 2015 announcement
We are very pleased to announce the availability of Scala 2.11.7! We would like to highlight the following changes: Exhaustivity checking for pattern matching is...
date-icon Tuesday, May 05, 2015 announcement
We are very pleased to announce the release of Scala 2.12.0-M1! Download a distribution from scala-lang.org Obtain it via Maven Central Code that compiles on...
date-icon
For more, visit our
News archive or Blog

Scala on Twitter


 
See more tweets, or
Follow Scala on Twitter
white Twitter logo