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.

  • 3
    recommended reading: Discuss this ${blog} – gnat Jul 29 '14 at 21:08
  • 1
    If you ask me, the article you linked to makes a few quite poor arguments (not to mention the quality of the writing). I wouldn't put too much stock in what it has to say. – Benjamin Hodgson Jul 29 '14 at 21:57
  • 1
    Bah. More and more I'm thinking this whole "immutable" thing is a good idea that's starting to stink of religion. – Rob Jul 29 '14 at 22:37
  • 3
    Joe Armstrong has publicly acknowledged that his objections against OO were based on severe misunderstandings of what OO exactly is. He has now realized that Erlang is actually a deeply object-oriented language (in fact, it might the most object-oriented language in mainstream use). – Jörg W Mittag Jul 30 '14 at 9:03
  • 9
    To expand on that: the first capture of archive.org of Joe Armstrong's rant is from April 2001. Joe wrote his thesis in 2003. During writing his thesis, he learned a lot about OO, and he realized that he had fallen prey to the common misconception that OO was somehow related to mutable state (it isn't, mutable state is completely orthogonal). Since then, he has acknowledged that his criticism of OO was wrong and that ironically Erlang is actually an object-oriented language (it has messages, it has objects which it calls processes, it has encapsulation). – Jörg W Mittag Jul 30 '14 at 9:17

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.

  • 3
    Agree wholeheartedly on the whole "java schools" bit, don't like that at all heh. Thank you very much, I'd vote up if I could. – Jake Jul 29 '14 at 17:45
  • 2
    Just to be precise: monads in general don't hide state, some monads do (e.g. IO). See among others stackoverflow.com/questions/2488646/… – thSoft Jul 29 '14 at 21:40
  • 2
    +1. This is a far more balanced and nuanced analysis than the article which the questioneer linked – Benjamin Hodgson Jul 29 '14 at 21:58
  • 2
    Joe Armstrong has publicly acknowledged that his objections against OO were based on severe misunderstandings of what OO exactly is. He has now realized that Erlang is actually a deeply object-oriented language (in fact, it might the most object-oriented language in mainstream use). – Jörg W Mittag Jul 30 '14 at 9:05
  • 2
    Jorg - could you post a link to Joe's followup? I'd be real interested to read it. And @radarbob, right on! – user949300 Jul 30 '14 at 16:24

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.

  • Excellent distinction between what should be immutable and what can have mutable state. Reading this, I realized that my more recent object graphs (more immutable than they used to be) basically follow this guideline without having it stated as clearly as you did. This is a good moderate antidote to the "mutable state is always evil" hogwash you sometimes hear. – Mike Supports Monica Dec 24 '14 at 7:27
  • @Mike: I think the real problem is that all object references in Java and .NET are fully promiscuous; any code which acquires or receives a reference to an object can share it with any other code, without restriction. Neither framework has any concept of a non-shareable reference field; structures and byrefs in .NET come close, but they are a rather limited in terms of what they can do or what they can prevent outside code from doing. In any case, I would offer up a fundamental saying with regard to mutable state: at 12:57am, an object may simultaneously represent... – supercat Dec 24 '14 at 17:19
  • ...the present state of a real-world object, and the state the object had at 12:57am. If the real-world state of the object changes, it will no longer be possible for an object to represent both. Sometimes it will be necessary to have the object continue to represent the 12:57am state, and sometimes the present state. The relationship between the 12:57am state and the present state cannot remain, however, if the present state changes. – supercat Dec 24 '14 at 17:24

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.

  • 1
    "If it's truly powerful it can simulate assembly language" - you swap the definition of powerful right there. When others say powerful, they talk about how well it allows programmers to abstract, which is a different story than computational power. – Phil Jul 30 '14 at 6:13
  • @Phil: abstract is another one of those words :) – Mike Dunlavey Jul 30 '14 at 14:46
  • Nah. You were talking about words. I was talking about ideas. Your 2nd and 3rd usage of the word power mean different things. Please don't mislead. – Phil Jul 31 '14 at 10:36
  • Btw, if you're interested, check out Racket, which is somewhat close to the approach you're saying in your 4th paragraph (enabling programmers to bring the language to the level of their problem instead of making them bring their problem down to the language's fixed set of constructs). It goes way beyond classic Lisp/Scheme, just in case anyone has that impression when first looking at it. – Phil Jul 31 '14 at 10:40

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.

  • An object should exist to protect the invariants of the concept it models. Presentation is an entirely separate concern and cannot be efficiently and maintainably handled by the same object, because an object cannot understand all the various ways it might be presented over time and space. Presentation must be handled through some other mechanism such as event streaming and materialized views if your goal is versatile, maintainable objects. The only time an object should change is if its concept is revised or its invariants change. – Andrew Larsson Jul 17 '19 at 23:00

Not the answer you're looking for? Browse other questions tagged or ask your own question.