Functional Refactoring

Refactoring is one of the important processes in software development.

The following is an exploration of code written in familiar imperative programming patterns, and refactored using a counterpart functional programming pattern. The goal is to build up a handy bidirectional map of corresponding imperative and functional patterns.

The implementations here use Scala to take advantage of its hybrid object-oriented and functional design, which caters to both imperative and functional patterns.

Definitions

Functional

adjective

  1. referentially transparent.

Referentially transparent

We use RĂșnar Bjarnason's definition of referential transparency

adjective

  1. an expression e is referentially transparent if for all programs p, every occurrence of e in p can be replaced with the result of evaluating e without changing the result of evaluating p.

Refactoring

We use Martin Fowler's definitions of refactoring

noun

  1. a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.

verb

  1. to restructure software by applying a series of refactorings without changing its observable behavior.

Table of contents

  1. Replace mutator method with deep copy
  2. Replace mutable variables with the state monad
  3. Replace loops with folds
  4. Replace exceptions with sum types
  5. Replace pass-through arguments with the reader monad
  6. Replace dependency injection with the reader monad
  7. Differentiate values with newtype
  8. Replace code with documentation
  9. Wrap side effects with IO
  10. Replace function with data structure
  11. Replace random access with zipper
  12. Replace accessors and mutators with lenses
  13. Replace malloc and free with a monad
  14. Replace pass-through variables with the reader monad

References

See also