Functions & Lambdas

Methods (def) belong to classes/objects; functions are objects (Function1[A, B] etc.).

9.1 Function values

val double: Int => Int = x => x * 2
val add: (Int, Int) => Int = (a, b) => a + b
val greet = (name: String) => s"Hi, $name"
val noArgs: () => Int = () => 42

double(5)     // 10
add(2, 3)     // 5

9.2 Placeholder syntax

List(1, 2, 3).map(_ * 2)          // x => x * 2
List(1, 2, 3).reduce(_ + _)       // (a, b) => a + b
List("a", "b").map(_.toUpperCase)

9.3 Methods vs functions

Methods (def) belong to classes/objects; functions are objects (Function1[A, B] etc.). Scala 3 converts methods to functions automatically (eta-expansion):

def isEven(n: Int) = n % 2 == 0
List(1, 2, 3, 4).filter(isEven)
val f = isEven       // Int => Boolean

9.4 Higher-order functions

def applyTwice(f: Int => Int, x: Int): Int = f(f(x))
applyTwice(_ + 3, 10)     // 16

def makeMultiplier(n: Int): Int => Int = x => x * n
val triple = makeMultiplier(3)

9.5 Composition

val inc = (x: Int) => x + 1
val dbl = (x: Int) => x * 2
(inc andThen dbl)(3)     // 8
(inc compose dbl)(3)     // 7

9.6 Partial functions

val safeDiv: PartialFunction[(Int, Int), Int] =
  case (a, b) if b != 0 => a / b

safeDiv.isDefinedAt((1, 0))     // false
List((4, 2), (1, 0)).collect(safeDiv)   // List(2)
val total = safeDiv.orElse { case _ => 0 }
safeDiv.lift((1, 0))            // None

9.7 Closures

var factor = 3
val scale = (x: Int) => x * factor
factor = 10
scale(2)       // 20 — captures the variable, not its value

9.8 Tupled & curried conversions

val add3 = (a: Int, b: Int, c: Int) => a + b + c
add3.curried(1)(2)(3)
add3.tupled((1, 2, 3))