About Functional Programming
An introduction to functional programming, exploring its core principles and benefits in JavaScript
Published
- 3 min read
Introduction
Recently, I’ve been exploring the fascinating world of functional programming. It feels like a good time to consolidate the resources I’ve found and highlight the ideas that have inspired me to delve deeper into this paradigm.
Why Functional Programming?
After immersing myself in articles, books, and videos by Eric Elliott, Brian Lonsdorf, Michael Fogus, Brian Beckman, and others, I’ve come to believe the following:
- Object-Oriented Design (OOD) and Relational Databases (RDBs) have inherent challenges: they tightly bind software and data within rigid structures that are difficult to adapt later.
- These rigid structures often require decisions during development stages where all relevant information isn’t available. Requirements inevitably evolve, but rigid structures resist change.
- Designing an optimal OOD or RDB from the start is nearly impossible because humans can’t predict the future.
This is why functional programming and NoSQL databases are gaining traction. As memory and computational power become cheaper and more abundant, they’re becoming viable alternatives for many applications. Functional programming, in particular, shines in distributed computing environments.
Fighting Complexity
As Brian Beckman aptly put it, the software development community today is “out of control in the complexity space.” The solution? Compositionality.
Functional programming presents a compelling alternative to classical Object-Oriented paradigms. While it has existed since the early days of computation, it hasn’t been widely adopted until recently.
Languages like JavaScript (and perhaps Scala) are among the first mainstream options to support functional programming constructs. With first-class functions, higher-order functions, and other functional capabilities, JavaScript enables developers to apply functional programming principles in ways older languages like C++, Java, and C# never could. Interestingly, as functional programming gains popularity, traditional OOP languages are also adopting functional features, making hybrid approaches possible.
However, functional programming can be challenging to grasp at first. Rooted in lambda calculus (or category theory, depending on your perspective), it’s riddled with terms like monads, monoids, functors, and applicative functors. Despite its esoteric terminology, the core idea is simple: build software by composing small, focused functions to create complex behaviors. This approach offers a significant advantage—unit testing becomes easier, often trivial.
First Steps
If you’re new to functional programming, start with the basics. The Functional Programming in JavaScript series by MPJ offers a beginner-friendly introduction. Concepts like higher-order functions, map, reduce, and currying are explained in a fun and engaging way.
Diving Deeper
Once I grasped the utility of functions like map
and reduce
, I sought more in-depth resources. Two standout books on functional programming with JavaScript are:
- Functional JavaScript by Michael Fogus: This comprehensive introduction covers concepts like purity, immutability, recursion, trampolines, and currying, with examples that emphasize JavaScript and the Underscore library.
- Professor Frisby’s Mostly Adequate Guide to Functional Programming by Brian Lonsdorf (aka Dr. Boolean): Though unfinished, it’s free and insightful. This guide leans toward a more functional programming style, akin to languages like Scala or Haskell. It complements Lonsdorf’s video series, Classroom Coding with Prof. Frisby, which is dense but rewarding.
For writing functional routines in JavaScript, Lodash—a more performant alternative to Underscore—is a fantastic library. For a purer functional programming approach, check out lodash/fp, Ramda, Folktale, and Fantasy Land. For an even deeper dive, consider PureScript or ClojureScript.
Advanced Concepts
For more advanced topics, Brian Beckman: Don’t Fear the Monad offers a practical glimpse into category theory and its connection to programming concepts like monads and monoids. Key takeaways include:
- Functions can be treated as data, modeled as lookup tables for nearly any input-output relationship.
- The historical divide in computing: the imperative camp prioritized performance (e.g., Fortran, C, Pascal, Java) at the expense of mathematical foundations, while the functional camp built on lambda calculus (e.g., Lisp, Haskell), sometimes sacrificing performance for purity.
- Complexity can be controlled by composing simple functions rather than adding ad-hoc features.