The substitution model evaluates a referentially transparent expression by replacing each term with an equivalent value, expanding variables and function calls until the expression reaches its simplest form. Computation therefore resembles algebra: substitute equals for equals, and preserve the program’s meaning at every step. section 1.3
The method works only when expressions have no observable effects beyond returning their values. A pure expression can be replaced by its result in any surrounding program; an operation that charges a credit card, mutates an object, or changes a builder cannot be safely replaced this way because evaluation changes the world or later results. section 1.3 section 1.5
Replacing an immutable expression
Given `val x = "Hello, World"`, evaluating `x.reverse` produces `"dlroW ,olleH"`. Substituting the value of `x` yields `"Hello, World".reverse`, which produces the same result. Repeating the expression remains equivalent because the original string is unchanged. By contrast, substituting repeated calls to a mutable `StringBuilder` changes its accumulated contents, revealing the failure of referential transparency. section 1.3
scala> val x = "Hello, World" x: java.lang.String = Hello, World scala> val r1 = x.reverse r1: String = dlroW ,olleH scala> val r2 = x.reverse #1 r2: String = dlroW ,olleH
Compare a variable-based expression with its repeated evaluation in the Scala REPL. section 1.3
