How to boost your object-oriented programming with functional programming
This is my summary of a BruJUG conference given bar Uberto Barbini about “How to boost your object-oriented programming with functional programming”.
This is maybe the first time I disliked a conference this year. Everything that Uberto said is true and relevant to the subject. But having read the title and the introduction, I expected something more practical on how to include functional programming concepts in my daily object-oriented experience. Instead of that, I got a strong advice to study functional programming and some good best practices about immutable objects and avoiding side-effects.
Anyway, I’ll write what I remember of that presentation, at least because talking in front of specialists is an uneasy exercise that deserves some attention and respect.
Let’s start with two interesting questions:
- What if object-oriented programming was wrong?
- Why does code quality matters?
Even if those questions may seem awkward at first sight, it is worth thinking about it and go beyond the standard answers that were hammered inside our heads while we were learning programming.
Bugs are inevitable at some point of our development. They cause frustration and delays. Many are easy to fix ans some can cause big troubles. A good code is thus not a code without bugs but rather a code where bugs are easy to find and to fix.
From the presenter point of view, worst bugs are often related to the state. I totally agree with that. So one solution is to defend your state like a castle so that state effects are limited to the object.
But even these days, even if we say or even sometimes think, we are still writing a lot of procedural code that is, code that describe a story like “do this, then do that, if the result is like this, do this other action” and so on. Take a look in a presentation layer based on Struts and chances are you’ll see what I mean.
Some framework seem to induce procedural paradigm which:
- is easy to write
- is hard to understand
- often involves a global state
Lisp is one of the first language to implement the functional paradigm and was published in the early 1960’s. In the early 1970’s, Smalltalk introduces the object-oriented paradigm.
But what is object-oriented programming?
- “It looks like a record with fields and methods plus keywords to define the scope.”
- “Object-oriented programming is an exceptionally bad idea which could only have originated in California.” Edsger Dijkstra
- “OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I’m not aware of them.” Alan Kay
- “An object has state, behavior, and identity.” Grady Booch
The idea of messaging if very present in Smalltalk itself.
A big problem is that a lot of programmers think they do good object-oriented programming because they use a lot of interfaces and design patterns.
To get some good advice about how to design an object-oriented application, one can read “Domain-Driven Design“, the Eric Evan’s famous book. One of this book concepts is to put emphasis on immutable value objects and avoiding side effects. Those practices makes object-oriented and functional paradigms not far from each other.
Functional paradigm recommandations
- use only immutable structures (messages)
- don’t use null objects or objects that are are not “ready”
- use pure functions (= without side effects)
- use closure to decouple behavior from data
Object-oriented paradigm recommandations
- inject dependencies
- don’t provide getters fro mutable state
- use interfaces for collaboration
- create simple aggregates
- use meaningful names
Popular object-oriented designs
Rebecca Wirfs-Brock classify software architecture into 3 different designs according to the way they locate data and behavior:
This is like procedural paradigm: one class controls the behavior and other classes provide the data.
This is also what Martin Fowler calls an anemic domain.
Despite from that, this kind of design has the advantage that all the logic is concentrated in one place. You don’t have to look everywhere to understand how a process is carried on.
Here the logic is spread across every objects. Each one does something very short and with as few dependencies as possible.
The drawback is that to have the complete point on something, you must navigate all the participating classes.
This kind of design is a compromise between the first two. The logic is spread into some classes that controls the behavior in collaboration with other small classes. They are thus pools of responsibility that can be used in relative isolation.
Learning new paradigms is interesting because it often leads you to a better understanding of the ones you use daily.
Functional paradigm has some very good best practices to include in your daily object-oriented programming like avoiding side-effects and using immutable objects as often as you can.
But besides those good pieces of advice, I must admit that this conference didn’t meet my expectations.
Anyway, the section below has very good books to read. Especially, don’t hesitate to order your own copy of domain-driven design which is a book I really appreciated.