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← the guideMulticore & Missions
§ 02 — Eras · 2004
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.
The JVM without Java’s ceremony: full functional programming and object orientation on a battle-tested platform.
Two sublanguages under one name — compile-time wizards and everyone else — plus compile times that tested loyalty.
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).
@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.
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).sum02 — 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.nameThe 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.
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
}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)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 case class: data with dignity — immutable, pattern-matchable, one line to declare. Objects and functions finally married, on the JVM.
case class Ship(name: String, tons: Int)
val total = ships.map(_.tons).suminstallbrew install scala
runscala fact.scala
Apache Spark, Akka, a generation of fintech backends — and Scala 3 is the nicest ML-family surface on the JVM.