What is it?
These are a set of arguments suggesting that Object Oriented Programming has 12 attributes, the benefits and deficiencies of each, and that Functional Programming addresses each of those.
Where does this come from?
This is from a page on the internet for a site that has now been taken offline, but is preserved on The Wayback Machine
What is the style of writing?
It is provocative and argumentative, seeking to make a point by exhaustive evidence and reasoning. The original title was “Object Oriented Programming is an Expensive Disaster that Must End”.
Why post this?
- I studied Eiffel at University in the mid 90s, and read Bertrand Meyer’s books on Object Oriented Programming and was fascinated by the promise of Object Oriented Programming and what it offered.
- In 2009 I became fascinated by the promise of functional programming, and how it offered an alternative to OOP which was the dominant paradigm at the time.
- Most arguments in favour of Functional Programming start with “the future is multi-core, and functional programming has a better answer than OOP”. This author starts with: “Here are the 12 attributes of functional programming, why they’re good, why they’re bad, and why functional programming has a better answer.”
- I don’t necessarily endorse the arguments of the author in their entirety, but am fascinated by the reasoning, and wanted to capture it and share it for further discussion.
- I wanted to summarise the arguments in a table, because lots of people don’t appreciate reading large slabs of text.
- I felt that the strength of the arguments was lost in the provocative style of the writer and felt the same arguments could be more convincingly presented.
- Even Bertrand Meyer, one of the chief academic proponents of Object Oriented Programming, finds himself arguing against the excesses of OOP, making the arguments that match the benefits of functional programming
Is it pragmatic?
This is not answering the question “How do I make my program/lifestyle better?” It answers the question “What are the reasons you would consider Functional Programming, looking at the world from an Object Oriented Programming lens?”
|Object Oriented Programming Characteristic||OOP Benefit||OOP Limitation||Analogue from Functional Programming (or alternative to OOP)|
|1. Encapsulation||Protection from unexpected changes to state.||Solving the state management problem by hiding it.||Use closures. |
Design your program not to mutate state.
Design your program around transforming the state.
|2. Polymorphism||We want flexibility in the way we dispatch execution.||Flexible dispatch based on the signature of a method, and the signature is almost always evaluated in terms of the data-type of the parameters being handed into the method||Multi-methods. [In Clojure. Typeclasses in Haskell are somewhat comparable.]|
|3. Inheritance||Treating similar but slightly different things the same way externally. |
Hierarchies of data types.
| Inheritance mixes together several things, ‘typeness’ [sic], interface and implementation. |
“Favour composition over inheritance” (Josh Bloch)
|Define data-type hierarchy independently of functions and independently of any state.|
|4. Abstraction||Use abstraction to decompose complex systems into smaller components. |
Denotes the essential characteristics of an object that distinguish it from all other kinds of object and thus provide crisply defined conceptual boundaries. Dependency injection is an example of depending on abstractions.
|Abstraction is not necessarily a subject within OOP. |
Bertrand Myer admits that OOP abstractions lead to factories and builders, the complexity of which lead to Inversion of Control Containers, which lead to greater use of composition.
The need for design patterns implies a deficiency of abstraction in the language itself.
|Solve your problem in terms of DSLs. |
Macro-systems can be a tool for abstraction.
|5. Code Re-use||Objects created for Object Oriented Programs can be reused in other programs. |
Many types, one interface promotes code re-use.
|Inheritance undermines code-reuse. Code reuse killed off by the amount of ceremony required to get anything done. (Factory patterns, dependency injection, getters and setters, annotations, verbose exception handling, etc).|
All the specificity of interfaces/classes kills your code re-use.
To achieve code re-use, you need to write a large number of small classes.
The rigidity of the Open-Closed principle tends to limit code re-use.
|Protocols. [In Clojure. Traits in Scala or Typeclasses in Haskell are somewhat comparable.]|
Flexible functions that can work on many data-types.
|6. Design Benefits||OOP forces planning which leads to better designs with fewer flaws. |
For large programs, OOP programs are easier to program than non-OOP ones.
|‘Forced Planning’ is an appeal to Waterfall development method. Risky because you gain benefits at the end of a long process. Only at the end of the software delivery can your users give feedback about whether your software helps them.||Organisations choose adaptive not predictive development methods like Agile.|
|7. Software Maintenance||Whilst more work went into designing an OOP program, less work is required to maintain it over time compared to a non-OOP program.||Maintainability depends on understandability, and OOP is a graph of mutating state that becomes less understandable as it grows. |
OOP tends to be bloated, containing lots of boilerplate code.
|Code written in a different style would be smaller and easier to think about.|
|8. Single responsibility principle||A class should have only one reason to change [structure of class]. |
Objects can be clearly reasoned about because they have focus.
|The reasons a class can change are driven by Conways Law (ie your program is shaped by the information flows in your organisation.)|
Single responsibility principle, gives you more objects, and gives you the responsibility for setting up all the dependent objects for your object, implying the need for IOC containers.
|You should have functions that operate on a data structure.|
|9. Open/closed principle||Enables low coupling, high cohesion.||Tends towards having too many small classes. |
Conflates three issues that should be separate:
1) establishing a data-type hierarchy
2) enforcing a contract
3) mutating state
Rigidity of this principle limits code re-use.
|Use protocols. [In Clojure. Traits in Scala or Typeclasses in Haskell are somewhat comparable.]|
|10. Interface segregation principle||Many client-specific interfaces are better than one general-purpose interface.|
No client should be forced to depend on methods it does not use.
Keeps a system decoupled, and so easier to refactor, change and deploy.
Useful ‘contract’ to describe the intent of the software.
|Data structures are spread out across multiple classes making the intent of the software harder to understand. ||Have a well-defined data-structure that many functions can operate on.|
|11. Dependency inversion principle||Helps to assemble components from different projects into a cohesive application. Provides a common pattern for wiring components together in a decoupled way. |
Solves the problem of instantiating the objects that an object depends upon.
|Solves a problem that only exists in Object Oriented Programming. IOC is a workaround for OOP.||Not required because the problem doesn’t exist outside OOP.|
|12. Static type checking||Enable the efficient and automatic proof of assertions about programs. |
Enable partial specification of your programs.
|OOP languages lose the benefits of the most advanced type-system features available in functional languages.||Use a functional language to get the benefits of the most advanced type-system features. |
There are exciting things happening with the Scala cats libraries and scalaz, inspired from Haskell that this author doesn’t address.