liveBook · Manning

Local reasoning

As explained in Functional Programming in Scala, Second Edition

Local reasoning is analyzing a component from its definition and inputs without tracking unrelated execution history or state changes.

Local reasoning analyzes a component from its definition and inputs, without tracking unrelated execution history or state changes. For a pure function, substitute its arguments into its body: the result depends only on that local computation. section 1.3 section 1.5

Immutable values versus mutation

Repeated evaluation of "Hello, World".reverse produces the same result, so each expression can be understood independently. A mutable StringBuilder behaves differently: evaluating x.append(", World").toString twice changes the second result to "Hello, World, World". Understanding it requires tracking the earlier mutation. section 1.3

Side effects such as mutation, exceptions, network access, and file access make meaning context-dependent. Moving effects outward leaves a pure core whose logic can be understood, tested, reused, and composed independently. section 1.3 section 1.5

Exceptions particularly obstruct local reasoning: the meaning of a throw changes according to the surrounding try block, while the function type does not communicate that failure is possible. Modeling errors with Option, Either, Try, or Validated makes failure explicit and lets map and flatMap preserve compositional reasoning. section 4.1 section 4.6

def buyCoffee(cc: CreditCard): Coffee =
  val cup = Coffee()
  cc.charge(cup.price)
  cup

Use the impure buyCoffee definition to identify payment as an effect entangled with computation, then separate the pure result from effect handling. section 1.3

How Functional Programming in Scala, Second Edition covers it

How deep it goes
Explains substitution, mutation, context dependence, and explicit error values, but stops short of formal proof techniques.
Examples
Contrasts immutable string reversal, mutable StringBuilder appends, impure payment processing, and exceptions caught in different contexts.
What it assumes
Assumes basic functions and expressions, while teaching referential transparency, purity, substitution, and explicit errors through concrete Scala examples.
What you can do after
Evaluate/understand pure components by substituting inputs, spotting context-dependent effects, and choosing explicit error representations.
How it connects
Connects local reasoning with referential transparency, purity, side effects, composability, substitution, and typed error handling.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Functional Programming in Scala, Second Edition. The section links point to the parts of the book it draws on.