This article is intended to help you methodically incorporate rad Functional Programming (FP) techniques into your everyday work.
It will not try to convince you that FP is a good idea (if you want to be convinced, read anything Eric Elliott has ever written on the subject) nor will it detail FP concepts or how to implement them. For an introduction on the problems and solutions outlined here, watch Brian Lonsdorf's talk, of which this article is tightly based on. In fact, this article is basically an outline of his talk, but with some practical advice and dank memes sprinkled in. Let's get started!
🚨🚨🚨 Update: I finished a real-world project where I put these practices to use. Check it out and let me know what you think!
Level 1 — Eliminate Loops
The easiest way to get started with FP is by using functions the language already provides for you. Namely:
reduce. Replace all for loops and mutating
forEachs with their functional alternatives.
forloop for a long, long time. Still, it's worth branching out from the native
Arraymethods to avoid re-writing a bunch of utility code in every project. Ramda is a great library when you need this extra horsepower. It's like a functional-by-design lodash.
Level 2 — Eliminate Useless Assignment
Level 3 — Eliminate
Maybe monad to codify the concept of nothingness.
Level 4 — Eliminate Exceptions
You have two options here. If you are using TypeScript or a static type analyzer such as Flow, I recommend #1. If not, go with #2.
Errors instead. The
functionin this case will have a union/variant return type e.g.
Int | Error.
- Use the
Level 5 — Eliminate Conditional Statements
The problem with conditionals in most languages is that they are statements, not expressions. This means you can't save the result of an if/switch statement to a value and you are left using temporary variables or wonky IIFEs instead.
Level 6 — Eliminate Callbacks
You almost certainly already do this one.
Level 7 — Eliminate Side-Effects
It should be noted that FP isn't about merely eliminating things. It's about making your code more reasonable and composable. When you are given more powerful abstractions, you need fewer of them.