Reading — step 1 of 5
Learn
~1 min readFunctions and Futures
Partial functions are like regular functions but only defined for some inputs.
val safeDivide: PartialFunction[(Int, Int), Int] = {
case (x, y) if y != 0 => x / y
}
safeDivide.isDefinedAt((10, 2)) // true
safeDivide.isDefinedAt((10, 0)) // false — divisor is 0
safeDivide((10, 2)) // 5
// safeDivide((10, 0)) // MatchError
orElse chains partial functions:
val handler: PartialFunction[Throwable, String] = {
case _: ArithmeticException => "math error"
case _: NullPointerException => "null deref"
}
val fallback: PartialFunction[Throwable, String] = {
case _ => "unknown error"
}
val full = handler.orElse(fallback)
Heavy use in Scala's standard library:
list.collect { case n if n > 0 => n * n } // map+filter via partial function
actor.receive {
case Greet(name) => sender ! s"Hello, $name"
case _ =>
} // Akka actors
lazy val — initialized on first access, then cached:
class Service {
lazy val expensiveData: Map[String, Int] = {
println("computing...")
loadFromDb()
}
}
val s = new Service
// expensiveData NOT computed yet
s.expensiveData // "computing..." — first access
s.expensiveData // (no print) — cached
Useful for:
- Expensive computations that may not be needed
- Resolving circular dependencies in singletons
- Lazy initialization of objects in tests
Thread safety: lazy vals are guarded by a synchronized init — safe but with double-checked locking under the hood.
lazy vs def:
def— recomputed on every callval— computed once at constructionlazy val— computed once at first access
Stream / LazyList use lazy evaluation — infinite sequences, only computed as consumed:
val naturals: LazyList[Int] = LazyList.from(1)
naturals.take(5).toList // List(1, 2, 3, 4, 5) — only first 5 evaluated
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…