Rabbi Lord Jonathan Sacks says: I have a friend in Washington. I asked him, what was it like being in America […]?
He said to me. Well, it was like the man sitting on the deck of the Titanic with a glass of whiskey in his hand, and he’s saying, “I know I asked for ice — but this is ridiculous.”
Edsger Dijkstra said once that Object-oriented programming is an exceptionally bad idea, which could only have originated in California.
It’s full of patterns and recipes that don’t help much in the way to deconstruct the domain and create a model. Functional programming, on the other hand, has a simple response to all this: functions!
SOLID is a mnemonic acronym for five design principles intended to make software designs more understandable, flexible, and maintainable.
Let’s consider a simple OOP pattern, the Single Responsibility Principle.
The principle states that every module, class, or function should have responsibility for a single part of that domain’s functionality and should hide that part from the outside.
Robert C. Martin expresses the principle as: “A class should have only one reason to change.”
Functional programming simply states that functions should have only one “function”, that’s all.
The Open-Closed Principle states that entities should be open for extension, but closed for modification. Code should be reused and extended without having to modify the original implementation.
In functional programming, inheritance does not play a role, and modification can be achieved simply with composition.
The Liskov Substitution Principle explains that objects in a program should be replaceable with instances of their subtypes without altering the truth of that program.
In functional programming, this pattern is the norm, since functions normally embrace polymorphic types (aka generics) to ensure that inputs can seamlessly be substituted without any changes to the underlying code.
The Interface Segregation Principle says that using many client-specific interfaces is better than one general-purpose interface.
In functional programming, functions living in a module, are using the inherent interface of that module, so even in a dynamically typed language, that interface still exists. And works as a charm.
And at the end, the Dependency Inversion Principle a bubbling, “High-level modules should not depend on low-level modules. Both should depend on abstractions.”
In functional programming, functions are abstractions in themselves, they care more about the “form” of the data instead of to which specific type they are attached to.
So while OOP presents patterns as ice, FP responds with, yes, functions, oh my, functions again!
This is ridiculous.