Low-Lying Fruits of Functional Programming
Here’s what an auto-suggest of “functional programming is …” looks like:
“FP is stupid” says a bunch of things, which I won’t look into too deeply here. I reckon that one of the reasons “FP is stupid” is that some of the tremendous productivity gains that FP unleashes are well-kept secrets.
Here are a few low-lying fruits that deliver a really big bang for a surprisingly small buck.
And depending on how you look at them, they aren’t even specific to FP, so you can apply them right away without leaving your current technology stack.
1. State and Data Design
Make illegal states unrepresentable.
— Yaron Minsky
FP proponents argue on the merits of code brevity. Less code generally has fewer bugs. But this is not true when code is “golfed” and some FP languages (yeah, I’m looking at you, Haskell) are particularly fine at this avocation pro obfuscation.
What’s lost in the noise is the higher principle at play here: code with Obviously No Bugs.
The expert programmer crafts negative space so as to make buggy code un-writable.
2. QuickCheck
Auto test-generation coupled with auto-shrinking of testcases is jaw-droppingly awesome. A savvy Developer in Test can leverage this into a fat raise during salary review.
If you do the work of 10 you deserve the salary of 10.
Regardless whether that’s in binary or decimal.
3. Parsing
The classical mantra of LISP is Code is Data.
Indeed, because the best way to solve some problems is to provide the user a way to script the solution, this classic is reborn clothed in the acronym of DSL: Domain Specific Language.
But what should the language look like?
Well, first we look at common cases to get a rough sketch. And then we figure out how scripts get entered for processing.
Parser combinators remove 80% of the pain and 100% of the fugliness from traditional parsing. They also serve as an exemplary model for compositional, denotative design.
Epilogue
None of the above involves grappling with fancy category theory. QuickCheck and parser combinators in their native implementations require only wielding, not smithing, monads.
Especially in data design, if you’re stuck wondering where to stick in a functor or applicative, chances are you’re missing the lower-lying fruit right under your nose.