Think Functionally to Simplify Code

Let the environment do more of the work

Functional programming keeps growing. While it has long been a popular topic in academic circles, and many of my CS-educated friends wonder why it took me so long to discover it, the shift in approach that functional programming requires made it a hard sell in the commercial world. As our computers have become more and more powerful and our problems more complex, functional programming approaches and environments seem better able to shoulder those loads.

Neal Ford, Meme Wrangler at ThoughtWorks, has been showing developers how to shift from classic imperative models to cleaner functional approaches. I was lucky to get to talk with him at OSCON, and we’ve also posted his OSCON talk, with many more concrete code examples.

The interview is a more compressed telling of the functional programming story. Ford talked about how this shift is like design patterns, but at a more fundamental level (1:16), and at this point there is no excuse to keep doing iteration instead of transformation (1:45).

Ford was blunt about how long-gone constraints still echo as issues in our languages (5:53) and the challenges of “language features coupled to every other feature creating combinatorial explosions” (4:10). There’s a lot of work ahead “removing the band-aids on languages that covered deficiencies” (3:10).

While Ford makes it clear that there is “no one true language” (7:12), he’s calling for developers to simplify with high-level abstractions (8:35). Although he used it sparingly in his talk, Ford noted how Clojure skips the temptation of “multi-paradigm seduction” (5:02) to leap wholeheartedly into functional possibilities.

The session is a much slower-paced exploration of shifting from Java to more functional approaches.

After explaining the challenges of change and some of the reasons programming looks like it does, Ford noted that functional programming is a case where academic pursuits have returned to merge with the mainstream (4:50).

For much of his talk, Ford focuses on solving a perfect number problem (7:38), building from a working imperative version to a functional version with additional advantages. After identifying issues with the imperative version (11:20), he takes a first small step toward functional programming, by minimizing shared state (11:52). Yes, it’s less efficient, but requires less scoping. That allows reuse at the method level, not just the class level!

He also explores how to solve the classification with Functional Java (25:43) and Groovy, (at 34:08) thinking in ever more functional ways.

I enjoyed many of Ford’s explorations along the way:

  • How higher order functions and lambdas obliterate the need for the OOP Command design pattern. (15:24)
  • Closures (18:05) as a first step toward the larger goal of letting the language manage state. (20:47)
  • “Life is too short for malloc.” (22:10)
  • Contrasting object-oriented programming classes that message each other with an approach that combines a few core data structures with functions that operate on them. (23:56)
  • “Think about the results you want to achieve, not the steps to achieve it.” (30:43)
  • Achieving reuse through transformations, not unique data structures. (33:13)
  • Pure functions that rely only on their parameters offer many advantages like memoization and consistency. (35:28)

Perhaps the most important and difficult lesson in Ford’s talk is what he calls on developers to do: “cede control” (38:43). Not of everything—there is work to do!—but of the many many tasks that languages and environments can handle.

tags: , , ,