← the guideMulticore & Missions

§ 02 — Eras · 2004

Scala

objects and functions, finally married, on the JVM

Left: era context, features, and the 101 hello. Right: 3 core concepts, 3 deeper 201 lessons, the factorial specimen, and where Scala lives today — each column scrolls on its own.

creators
Martin Odersky, 2004
status
alive (niche-strong) · big data (Spark), fintech

The problem it solves

The JVM without Java’s ceremony: full functional programming and object orientation on a battle-tested platform.

The problem it carries

Two sublanguages under one name — compile-time wizards and everyone else — plus compile times that tested loyalty.

Key features

case classes
Immutable data with pattern matching, equality and copy, in one line.
traits and mixins
Compose behaviour from pieces, linearized like Smalltalk’s.
for-comprehensions
Monadic sequencing that reads like a loop; Spark queries are written this way.
immutability by default
vals are values, so sharing is safe by construction.

101 — hello, world

Session one is the smallest program that still counts as speaking Scala: what every tutorial prints first, in the dialect that mattered when the language arrived (2004).

the first program2004
@main def hello(): Unit =
  println("Hello, world")

101First contact — hello world and 3 ideas that define how Scala reads. 201 — 3 lessons on mechanisms you meet after the factorial specimen: the sharp edges practitioners actually use.

101 — core concepts

3 fragments, each naming a habit of mind in Scala. Read the note, then the code — together they are the 101 in one sitting.

01 — case classes

Immutable data with pattern matching, equals and copy for one line.

case class Ship(name: String, tons: Int)
val total = ships.map(_.tons).sum

02 — pattern matching

Decompose data by shape — the FP half of the marriage.

ship match
  case Ship("Perch", _) => "the perch"
  case Ship(n, t) if t > 20 => s"big: $n"
  case _ => "other"

03 — for-comprehensions

Monadic chaining that reads like a loop — Spark queries are written this way.

for
  s <- ships
  if s.tons > 20
yield s.name

201 — going deeper

The 201 assumes you have read the 101 and the specimen. Each lesson is one mechanism — what it is for, how it looks in code, and the trap or payoff that makes Scala distinctive at scale.

  1. type classes and implicits
  2. collections and laziness
  3. Option and Either

type classes and implicits

A type class provides behaviour for a type; implicits summon it, or summon the conversion that produces it — the mechanism behind Scala’s flexible APIs and its sharp edges.

trait Show[A] { def show(a: A): String }
object Show {
  implicit val intShow: Show[Int] = a => a.toString
}

collections and laziness

Seq, Set, Map and View differ in how much they compute and when; View exists to defer work you may not need.

val lazy = ships.view.map(_.tons).filter(_ > 20)
val eager = ships.map(_.tons).filter(_ > 20)

Option and Either

Absence and failure are values, not exceptions: Option models “maybe”, Either models “this or that”, and pattern matching forces the case to be handled.

val tonnage: Either[String, Int] =
  Right(24)

tonnage match {
  case Right(t) => println(t)
  case Left(e)  => println(e)
}

The specimen — factorial

The case class: data with dignity — immutable, pattern-matchable, one line to declare. Objects and functions finally married, on the JVM.

the case class2004
case class Ship(name: String, tons: Int)

val total = ships.map(_.tons).sum

Run it today

installbrew install scala

runscala fact.scala

Where it is now

Apache Spark, Akka, a generation of fintech backends — and Scala 3 is the nicest ML-family surface on the JVM.