Appendix A: Scala 3 Syntax Notes for This Book
This book uses a handful of Scala 3 features in nearly every example. If you are coming from Scala 2, Java, or another typed language, this appendix is the short reference for the syntax you'll see — just enough to read the chapters comfortably.
Indentation-based syntax
Scala 3 lets you replace braces with significant indentation. A class body, method body, or block opens with : (for definitions) or is simply indented:
class Greeter:
def greet(name: String): String =
val message = s"Hello, ${name}"
messageBraces still work and are still useful — for a short lambda passed to a method, the book often keeps them: design.build[App] { app => … }. Use whichever reads more clearly; they mean the same thing.
@main entry points
A program's entry point is a method annotated with @main, not a magic signature on an object:
@main def run(): Unit =
println("started")Arguments become method parameters. @main def fetch(args: String*) gives you the command-line arguments directly, which is how the CLI app in Chapter 2 starts.
given / using — contextual parameters
A using parameter is supplied by the compiler from a matching given in scope, instead of being passed explicitly at the call site:
given Weaver[User] = Weaver.of[User]
def toJson[A](a: A)(using weaver: Weaver[A]): String = weaver.toJson(a)
toJson(user) // the Weaver[User] given is found and passed for youThis is how Weaver codecs and other typeclass-style values travel through the code without cluttering every signature. A derives clause (case class User(...) derives Weaver) generates the given for you.
Enums and pattern matching
Scala 3 enums declare a closed set of cases, which you then match on:
enum Color:
case Red, Green, Blue
def hex(c: Color): String =
c match
case Color.Red => "#f00"
case Color.Green => "#0f0"
case Color.Blue => "#00f"The compiler warns if a match misses a case, so adding Color.Black later points you at every place that needs updating. Uni uses enums for closed sets like log levels and RPC status codes.
Extension methods
An extension adds methods to a type you don't own:
extension (s: String)
def shout: String = s.toUpperCase + "!"
"hello".shout // "HELLO!"Several Uni APIs read fluently because of extensions — the shouldBe in Chapter 4's tests is an extension method on any value.
Why new is almost never needed
Scala 3 lets you construct a class by calling it like a function, so the book writes StringBuilder() and FakeDatabase(), not new StringBuilder(). You'll only see new in this book for the rare anonymous-class case (overriding methods inline, as with a WebSocketHandler). If you wrote Scala 2, dropping new is the habit to unlearn first.
← 16. Capstone — A Bookmarks Service | Next → Appendix B: Uni and Airframe
