A pure function returns a result determined solely by its inputs and has no observable side effects. Give it the same inputs again, and it returns the same result without changing anything else. This makes its calls predictable: a pure expression is referentially transparent when replacing it with its value leaves the program’s behavior unchanged. section 16.1 section 16.1.2
Sum without consuming the array
Consider `arr = [1, 3, 5]`. A method that sums by repeatedly calling `arr.shift` returns 9, but empties the caller’s array; a second call returns 0. Defining the method as `def sum_of_parts(arr); arr.reduce(:+); end` instead returns the sum without modifying `arr`, so the same array can be used again. section 16.1.1
Ruby methods can express this idea without special function syntax. `3 + 4` is a call to `3.+(4)`: with the same receiver and argument, it returns 7 without modifying either. Likewise, `map` produces a new array rather than changing its receiver. When reasoning about a call that takes a block, consider the block’s behavior too. section 16.1.2
Look for effects beyond the return value:
- Mutation: `upcase` leaves a string alone, while `upcase!` changes it; appending to an array and deleting from a hash also change state. section 16.1.3
- External effects: terminal output, database changes, and web-page updates are observable side effects. An unhandled exception is also treated as a side effect here. section 16.1.1 section 16.1.3
Removing stored state can move a design toward pure functions, but it does not make every method pure. A grading calculation can take scores and return a letter instead of storing the letter in an instance variable. Issuing the report still prints output. Keep such effects where they are needed rather than treating all state changes as mistakes. section 16.1.4 section 16.1.3


















