In one of many anti-OOP rants on cat-v.org I found a passage by Joe Armstrong raising several objections against the OOP model, one of which was the following:
Objection 4 – Objects have private state
State is the root of all evil. In particular functions with side effects should be avoided.
While state in programming languages is undesirable, in the real world state abounds. I am highly interested in the state of my bank account, and when I deposit or withdraw money from my bank I expect the state of my bank account to be correctly updated.
Given that state exists in the real world what facilities should programming language provide for dealing with state?
OOPLs say “hide the state from the programmer”. The states is hidden and visible only through access functions.
Conventional programming languages (C, Pascal) say that the visibility of state variables is controlled by the scope rules of the language.
Pure declarative languages say that there is no state.
The global state of the system is carried into all functions and comes out from all functions. Mechanisms like monads (for FPLs) and DCGs (logic languages) are used to hide state from the programmer so they can program “as if state didn’t matter” but have full access to the state of the system should this be necessary.The “hide the state from the programmer” option chosen by OOPLs is the worse possible choice. Instead of revealing the state and trying to find ways to minimise the nuisance of state, they hide it away.
What exactly is meant by this? I have very little low level or procedural experience, mostly OOP, so that probably explains how unfamiliar with this I am. And from a more modern standpoint, now that most of the Object-Oriented hysteria is passed (at least as far as I can tell), how accurate/relevant do you guys think that passage is?
Thanks for your help.
7
What exactly is meant by this?
In this context, it means that OOP obscures the state of a program by hiding it away from the programmer but still making it visible via (leaky) accessor methods. The argument is that by obscuring the state, it makes it more difficult to work with, and by extension lead to more bugs.
how accurate/relevant do you guys think that passage is?
I feel that it is relevant, but misdirected. There is absolutely an issue if your class leaks the concept of its state to the outside world. There is absolutely an issue if your class tries to obscure the state when it should be manipulated by the outside world. That though is not a failing of OOP as a whole, but with the individual design of the class. I wouldn’t say that hiding state itself is an issue – monads do this in functional programming all the time.
In the best of cases, OOP works like the best mix of functional programming and procedural – people can use the class “as if state didn’t matter” because the private state used to protect the invariants of the class is hidden, but have freedom to use a well defined public state of the class which abstracts away the details.
Does OOP make it harder for people to achieve this best of cases? Possibly. “Java schools” and the whole Shape/Circle/Rectangle or Car has Wheels school of teaching OO probably have more to blame than the approach itself. Modern OOP takes quite a bit from functional programming, encouraging immutable objects and pure functions while discouraging inheritence to help make it easier to design classes that work well.
6
Reasoning about a system will be difficult if there are pieces of mutable state that have no single clear “owner”. That doesn’t mean that objects should never have mutable state, but rather that objects which do have mutable state should not be used in ways where ownership might be unclear, and conversely that objects which will need to be freely passed around without tracking ownership should be immutable.
In practice, efficient programming frequently requires that some objects have mutable state; such state, however, should be confined, however, to unshared worker objects. Consider the IEnumerable
/IEnumerator
interfaces in .NET: if a collection implements IEnumerable
, it will allow the items to be read out one at a time. The actual process of reading out a collection will often require keeping track of which items have been read (a piece of mutable state), but such state is not contained within an implementation of IEnumerable
. Instead, IEnumerable
provides a method called GetEnumerator
which will return an object that implements IEnumerator
and contains enough state to allow items to be read out from the collection. The fact that the object contains such state will pose no problem, however, if object implementing IEnumerator
is not shared.
The best pattern in most cases is to use a mixture of objects which are freely shared but will never be modified (at least not after they’ve been shared), and objects which have a clear owner, and may be freely modified by that owner, but are never shared with anyone.
3
At the risk of going beyond answering the question, it’s easy to see flaws in the idea of OOP, but I’m inclined to think the power of an idea is reflected in it’s ability to be abused.
After all, everyone has their favorite language, that they describe in terms like “very very powerful” meaning they really really like it. But the wonder of computational universality is that no matter how glorious a language is, if it’s truly powerful it can simulate assembly language. And if it can, someone will see that it does.
(Not that there’s anything wrong with assembly language.)
My personal feeling about the OOP bandwagon is that it represents a stunting of people’s education in software engineering / computer science.
They are stunted at a level where they think it’s all about data structure.
Classes, inheritance, containers, iterators, hash maps, properties, state hiding, etc. – all about data structure – the more the merrier.
I personally would like to see a next level where people would learn to solve problems by looking at them linguistically.
Where they would understand the concept of domain-specific-languages, how to easily make them and let their creation be an integral part of problem-solving.
It’s not incorrect to say that a data structure is a language.
People should have that skill of language design, so they are not just bumbling through it.
Then as a next level, I would like to see artificial intelligence reinvigorated.
I would like to see programmers move beyond bytes and threads and virtual function tables and CUDAs and move into how to get machines to reason, learn, and create.
I know this has advanced very far in little corners of the field, but nowhere near broadly enough.
4
Accessibility is not a feature of OOP, it is specific to implementations such as Java and Microsoft dotNET. The main feature that defines OOP is polymorphism.
Anyway, by hiding the object state, there is no way to create a meaningful API. Presentation is a vital component of real-world OOP. Those who disagree likely have an irrational hostility towards software industry, which makes their opinion irrelevant from my point of view.
Websites like the one you linked are notorious for extremely rigid thoughts and criticism on new technology. Some people just don’t get it.
1