Skip to content
AgileLogics
4 min read

Blocks and Expressions

Prerequisites: if expressions

In Scala, almost everything is an expression — something that produces a value. This one idea explains much of how Scala code looks.

Blocks return their last expression

@main def blocks(): Unit =
  val total =
    val price = 20.0
    val tax = price * 0.2
    price + tax
  println(total)
24.0

A block — here, the indented lines under val total = — runs its lines in order, and its value is the last expression. price and tax exist only inside the block, which keeps helper values out of the way.

Expressions everywhere

@main def expressions(): Unit =
  val n = 7
  val parity = if n % 2 == 0 then "even" else "odd"
  val size = n match
    case 0          => "none"
    case x if x < 5 => "a few"
    case _          => "many"
  val squares = for i <- 1 to 4 yield i * i

  println(s"$n is $parity and $size")
  println(squares)
7 is odd and many
Vector(1, 4, 9, 16)

if, match, for ... yield, and try all produce values. (Each gets its own lesson.)

Unit: the value of "doing something"

Expressions that are run only for their side effect — like println — return Unit, whose only value is ():

@main def unitValue(): Unit =
  val result = println("printing...")
  println(result)
printing...
()

Seeing () or a type of Unit where you expected a real value usually means a branch or block ended with a statement instead of the value you meant to return.