liveBook · Manning

Smart constructor

As explained in Functional Programming in Scala, Second Edition

A smart constructor is a constructor-like function that creates a value while returning an abstraction's base type rather than a concrete data-constructor type.

A smart constructor is a constructor-like function that creates a value while adding an invariant, changing the signature, or returning an abstraction’s base type instead of a concrete data-constructor type. The real constructor remains available for pattern matching, while ordinary construction goes through the smarter interface. section 5.2.1 section 5.6

LazyList uses a smart cons constructor to control evaluation. Its by-name head and tail arguments become memoized lazy values, so forcing either computation once caches the result for later forces. This avoids requiring callers to create thunks or perform caching manually. section 5.2.1

Memoizing a lazy Cons node

Direct construction can recompute work: val x = Cons(() => expensive(x), tl). A smart constructor instead accepts by-name arguments, stores them in lazy vals, and constructs Cons(() => head, () => tail). Repeated access then returns cached values. section 5.2.1

def cons[A](hd: => A, tl: => LazyList[A]): LazyList[A] =
  lazy val head = hd
  lazy val tail = tl
  Cons(() => head, () => tail)

Inspect the complete cons definition, including by-name parameters, lazy caching, and construction of the underlying Cons node. section 5.2.1

Common smart-constructor responsibilities include:

  • Enforce an additional invariant or validation rule. section 5.2.1
  • Expose a different signature, such as by-name parameters for deferred evaluation. section 5.2.1
  • Return the abstraction’s base type, such as LazyList[A], rather than Cons[A] or Empty. section 5.6

How Functional Programming in Scala, Second Edition covers it

How deep it goes
Works through by-name parameters, lazy vals, cached forcing, and base-type inference, but defers broader lazy construction techniques.
Examples
Demonstrates memoized cons, empty, and LazyList.apply construction, alongside direct Cons construction that recomputes an expensive expression.
What it assumes
Assumes familiarity with Scala functions and case classes while teaching by-name parameters, thunks, memoization, and base-type inference.
What you can do after
Build it from scratch by defining constructors that defer evaluation, memoize results, enforce invariants, or return abstraction-level types.
How it connects
Connects smart constructors with LazyList, data constructors, by-name parameters, thunks, memoization, subtyping, and type inference.

Also explained in

Compare how 3 books explain smart constructor →

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.