Why Misunderstanding Concurrency-Oriented Programming Sucks
This is a response to Why Misunderstanding OO Sucks.
As systems get larger and more complex then the reductionist view becomes less and less relevant. It continues to have useful inputs into the design, but the development process itself must become more holistic in outlook or it will fail to produce a harmonious whole.
This is an appealing view. It’s of course amusing to throw this at Joe Armstrong, who not only pretty much implemented Erlang but has had his hand in a number of largish systems. If Joe’s perspective were merely reductionist, I’d find it hard to believe that his creation is running the majority of telecom systems in the world. That can’t be a trifling matter.
I think it’s insane to call OO a process and emphasize its effect on software design. If that were the case, how did we have the OO revolution in the 80’s, and not have agile development until the late 90’s? No, if OO had anything to do with process, it had to do with waterfall-model spec, design, then implement thinking. And yet the strongest OO systems today, Smalltalk, Ruby, Python and Io, have nothing to say about the development model, because it had nothing to do with their development or use. If anything, Ruby has a model in agile, thanks to the agile people being overly fond of it.
As for everything being an object, this is only partly true. To make this statement true we have to group together two varieties of object—those with identity and those which are values. Many object oriented languages do in fact conflate these two types of data structure, but of course many do not.
The only OO languages that are a joy to use are those which “conflate” these two things. In Ruby, for example, I can define whatever method I like on integers and call it on a literal, such as the built-in 1.upto(10) { |x| puts x }. Ruby would blow without this feature. In fact, even Python has slowly started to adopt this as a feature. It’s Java and C++, which stupidly maintain a separation between objects and types, that receive the ire of programmers who wish to treat things uniformly.
This difference between object and value semantics is as fundemental to understanding object oriented design and programming as that of function composition is to functional programming. It is unfortunate that it is generally rather badly taught.
I would like to believe that, having been an OO programmer for five years, that statement would have meaning to me, but it doesn’t, for the reasons mentioned above.
If we could build systems that didn’t need to bother with state our jobs would be much easier, but the resulting software would be much less useful and interesting.
That’s interesting, because as mentioned above, Joe Armstrong’s Erlang is now the backbone of the telecom industry, and it doesn’t support modifying your variables. Now, it certainly has state, just like Haskell has state — implicit state, or state managed through a mechanism so alien that OOP isn’t even a concept that can be applied to it.
This shocked me when I started learning functional programming about a year ago. I looked at ML and I snorted. How can this possibly be usable without being able to factor my code into classes? What am I going to do when the client calls me up and I need to have the program do something totally different?
Well, it turns out in functional programming, we have a type system that makes some of OOP unnecessary. Firstly, it’s simple to construct types which enumerate all the different ways of carrying around state you would use in an object. Secondly, we have a pattern-matching system which makes it both possible and cheap to write functions that do different things depending on the nature of their input.
The straw man argument in that is: aha! What about when you add a new alternative to your type, then you have to go through all those functions again and update them! Supposing this is true, consider how hard it is to add a new operation in OO. Say you come up with some new method you need — Aha! You have to go through all those classes and implement that method. And that is the worst case in OO.
OO is, in general, a very good thing when compared to procedural languages. It’s nutty to defend Java and C++ type systems when Ruby and Eiffel exist.
The interesting thing about OO’s lamentable state is quite clear if you look at the history. C++ was made to be as backwards compatible with C as possible. Java was made to be essentially a simplification of C++ with a few improvements. The functional language community wasn’t in a position to have these worries, because these worries come from having a user base, so instead it came up with more and more amazing languages, trying desperately to get people interested.
Actually, this was the second time this had happened. The same thing had basically happened with Lisp in the late 70’s. Everyone was using it and making incompatible variations. Then eventually they decided to have a big standardization process during which the AI winter apparently came and everyone switched to C++. I guess.
What makes the debate bizarre is essentially the Smalltalk factor. While everyone was switching to C++ and lauding the wonder that is OO, how many people were using Smalltalk? It’s not like Smalltalk went away, but it seems to have as many users now as it had after everyone defected for the other. And yet it’s so much more capable and powerful. I find it hard to believe that C bindings could be so difficult or that optimizating compiler technology could be so out of reach when C++ is about the most complex language being used (after FORTRAN or Ada, probably).
In my opinion, I should be spending more of my time worrying about what I’m doing with data rather than worrying about the data itself. OO is definitely interested in helping you worry about the data itself. This is a natural fit for boring business data processing, which is why Java’s being hailed the new COBOL. The crown belongs to the functional languages, but boredom has killed the king.