The past few months have found me relearning functional programming, and by reference, OCaml. Coming from a legacy of imperative, von Neumann-style coding, functional programming is a challenge to learn and adopt. Except, not really. When I first learned to program, all that existed with functions. We wrote functions. Functions called other functions. It was functional.
“Why bother?”, I hear you cry. Functional programming is for academics. It’s for math-heads. It’s for people who know what foldr() and map() are. Who understand monads and monoids and functors and applicatives and monads. Lambda functions.
“Why bother?”, I ask myself, as I run my first app in a language that I’ve never used before.
Well, because it’s easy. Oh, not in the sense of easy-peasy. It’s easy like plucking a violin is easy after years of playing the banjo. It’s easy like driving a car is easy after you’ve ridden a horse for years.
Functional code tends to be a lot more composable. There’s less repetition. And, there’s less mutable state.
This last point is really important. A lot of complexity in applications I’ve worked with comes from mutable state and nested callbacks.
Functional programming proves that simplicity really is better. Code which is simple to write, is simple to read and is simple to reason about. Code which can be reasoned about without referring to an extensive style guide is good code.
Learning a new programming language is a challenge. OCaml is a particularly challenging one. You see, it has features that are a bit like Haskell and a bit like Lisp, but the conciseness of Lisp and the strictness of Haskell. It’s a very concise language. A single line of code can do something that would take many lines in other, non-FP languages.
The syntax is cryptic. It has some very odd syntax such as square brackets for functions and exclamation marks for objects. It’s a language that doesn’t compromise.
It’s genuine. It’s honest. It’s as if someone had said: “We know what we want to do. Let’s do it.” Contrast this with Python, for example, which has a very light syntax, but layers of complexity and frameworks that have to be learnt to use it effectively.
The power of the language is in its library. There is nothing in the language that can’t be expressed in OCaml. This means that despite the initial strangeness of the language, you can write functional code as quickly as anything else.
Also, OCaml is not a scripting language. It is compiled and requires a compilation step before it will run. The compiler is very strict. You have to think through what you're doing, what are the types, and what output you want in the end. This makes it slower to develop than some other languages.
For example, say you have to parse some JSON. Here's a walkthrough on how to define the JSON structure, and then parse it functionally. It seems complex. Once you get the hang of it, it's really far simpler and less error prone than other ways in imperative languages.
In short, it’s not a trivial or easy language to learn. It’s a language that demands time and practice in order to fully understand. However, I am quite taken with it, and I like that.
Functional Programming, Redux.
Functional programming is good at making code easy to reason about. Redux, on the other hand, is good at making code easy to maintain.
As an example, part of this post is written by my hands, the other via REST API calls to OpenAI API. It's a function for the reader to figure out which parts are written by me or by a series of OCaml functions.