IMHO this is a pretty poor rant. Let me argue each point:
* Data structure and functions should not be bound together
In some cases encapsulation works really well. For example GUI elements. It is less true for "process-oriented" components. But the arguments he makes don't seem very well thought out.
* Everything has to be an object
I actually agree here. To my mind, the biggest problem with OOPS is that is slowly devours all other concepts until we are left trying to force-fit all problems into the OOPS mould.
* In an OOPL data type definitions are spread out all over the place
This just ignorance.
* Objects have private state
This is also a good point. Having state actually tends to being a "bad" thing to do. Of course, the entire purpose of the object is to capture some invariant, but an object doesn't make that clear. Many objects contain instance variables that should actually be parameters.
* Why is OOPS popular?
Because it makes it easier and safer to get programmers working together as a group. The vocabulary of available objects is a simple and somewhat elegant way of communicating.
He is actually correct that in an OOPL data type definitions are spread out all over the place
In a typical OO language all the code belongs in classes, and there is no way of telling which classes define the essential data types and which are mostly placeholders for code. There is no way to tell at a glance what are the important data structures. Just look at any open source Java project.
I use python and I find myself using more functions and fewer and thinner classes recently. In particular, if some state is transient, I find it is much better to keep it in local variables of the more abstract functions than obscure it as object state.
Because it makes it easier and safer to get programmers working together as a group.
Making OO the ultimate dogfood.
Whenever I encounter any kind of new "thinking", the first question I ask is, "Who is it good for?"
Ultimately, OO was made for us, not our customers. True, anything that helps us helps our customers, but I'd prefer to ask a more basic question...
If we have so many programmers that we need new technologies to work better together, are we doing something fundamentally too complex to begin with? Most of us aren't working on the space shuttle. We're doing relatively simple bread and butter apps moving data through logic. Before we surrender to OO, maybe we should take a closer look at why we need "easier and safer" ways to work together. For most of us, a simpler approach than OO often makes more sense. I suspect that's OP's biggest point.
He probably has a point in some ways, but some of the points seem so bad they are almost impossible to rebuff - e.g. functions are functions, data is data, therefore they must be separate?
Additionally, he's run up against the pitfall with OO - it actually lacks a definition. It's got lots of dimensions and facets, and each implementation interprets these in it's own way... e.g You could argue that SmallTalk's message passing metaphor was the precursor to Erlang's model.
There are plenty of OOPLs where this is not the case. For example C++ or Python.
> Why is OOPS popular? Because it makes it easier and safer to get programmers working together as a group.
That's true. But the main reason why OOPL is popular is because it makes programming more productive, whether there's one programmer writing the code or lots of them.
I actually wanted to like this post but visitor4rmindia is right, it is, sadly, a fairly ill-thought-out rant. For example: 'Consider "time". In an OO language "time" has to be an object. But in a non OO language a "time" is a instance of a data type'. In an OO language like Ruby, A time value is an instance of a class "Time", in a non-OO language, a time, variable may be an instance of a built-in type "time" if you are really lucky (PL/SQL) but it is more likely to be an integer or a string or a structure or all of these at different times.
This is also a good point. Having state actually tends to being a "bad" thing to do. Of course, the entire purpose of the object is to capture some invariant, but an object doesn't make that clear. Many objects contain instance variables that should actually be parameters.
Yikes guilty as charge here as I currently have a unhealthy fascination for the use of instance variables if not all in most of my objects. Thanks for the heads up.
This article is easier to appreciate if you view it as a window into the thinking style of a another programmer, rather than an actual argument about what is right or wrong. (That is, patch your local branch of the headline to "Why OO Sucks For My Way Of Thinking".)
The impressions I get are that Armstrong likes to stay close to a core set of raw data structures; he's more about the flows than the stocks; he finds delegation and specialization more frustrating than helpful; and he would rather build a combustion engine than an office building.
(He's probably an ISTP personality type at work but has put on his ISTJ hat for the purpose of writing this article.)
As a disclosure, I've been using Ruby for the past three years, and it's about as object-y as you can get. However, Ruby opened my eyes a bit to exploring other languages. Point is, as I started looking at other languages in depth, I found myself using objects a little bit less, especially in the design pattern sense. Some problems in the traditional 23 design patterns just disappear in dynanmic languages. After programming in Lua and Javascript, I find objects nice, but optional.
Nowadays, I sort of just use classes to scope and namespace. I keep state in classes when it makes sense.
To counter the point about state, Erlang programs do have state. They're just contained locally within a function. Since Erlang has tail recursion, you just call the same function recursively and pass the state variable you want to keep at the very end of the function for the lifetime of the program. Because it's tail recursion, there's no stack overflow. Also, Erlang threads can keep 'state' inside of the Mnesia database that comes with Erlang.
State is only evil when it's shared. Because state is contained locally in a function, a single Erlang thread can do whatever it wants, whenever it wants with those variables. Threads communicate through message passing. Therefore, no need for locks, mutexes or semaphores. Along with the low overhead of thread creation (~300 bytes) they're part of the reason why Erlang has great concurrency properties.
Objection 1 - Data structure and functions should not be bound together
This is not true of "OO", it's just true of OO in languages like C++ and Java. These languages got OO horribly, horribly wrong; so if you use them and dislike OO, it's possible that you dislike the language -- not OO.
If you use CLOS, you'll see that functions are functions and data are data. CLOS just gives you some tools for calling different functions depending on the type of the data and for specializing subtypes. This is OO done right, and it is not what the author of this article is referring to.
Objection 2 - Everything has to be an object.
Everything has to have a type, yeah. But the line between "built-in type" and "object" should be blurry, and in CLOS it is. Again, if you are hating OO because of Java's implementation quirks...
Objection 3 - In an OOPL data type definitions are spread out all over the place.
I am not sure what the problem is here. Unless your code is all in one file, this is going to be a problem regardless of the programming "paradigm" you choose.
When writing Lisp, I often put all my class and method definitions for one chunk of the app in the same file. I think this is what the author wants to do, and it is do-able and commonly done in CLOS. In Java, yeah, you have to put each class in its own file. That is irritating, but the problem is not OO.
Objection 4 - Objects have private state.
This is true. I prefer to write OO code that maps one object to another, rather than mutating an object's internals. The sad reality is that this approach is slower and uses more memory than the mutation approach, but I think it's easier to reason about and maintain. Computers are fast, anyway.
So while it's possible to misuse OO, whatever that means for your particular tastes, it's also possible to not misuse it. If you hate OO, it is possible that you are doing it wrong.
For Objection 1, Smalltalk also works since it's dynamically typed. There may be a bit more work to do to get it to do stuff in a CLOS-like way though.
For Objection 2, well as you said, the distinction should be blurry. I really don't understand what his objection to Time being an object is. What Erlang is doing with deftype is basically creating a new "constructor" for an object that includes bounds-checking.
The problem in Objection 3 is that he's dealing with file-based languages (and so are you). If you use any Smalltalk, you'll find a nifty browser that organizes things by package name, and there are even categories for methods.
I wish people would stop posting ill-informed rants on Hacker News.
I have to say that I agree with this only as long as we're talking about languages that don't have excellent OO capabilities. C++, Java, C#, and most others failed to impress me with their approach to OOP. But then I got to work in Smalltalk, and it dawned on me: "this is what OOP is supposed to be like."
"Data structures just are. They don't do anything. They are intrinsically declarative. 'Understanding' a data structure is a lot easier than 'understanding' a function. "
I'm possibly damaged from a few years of OOP but how do you separate a data structure from its functions? e.g. How can a B-tree mean anything separate from its search/insert/delete operations?
In the case of a B-Tree the data structures are the keys/offsets (and possibly values) that are stored in the tree and not the tree itself.
For instance most examples on the net just assume keys to be long numbers but that is obviously insufficient for an actual application. Keys could be 20-bit hashes, strings, floats, doubles etc. The same applies to a lesser degree to the offsets (at leaf node level) and any embedded values.
Plus it is interesting that you view a B-Tree as an object - when I think about it, I categorise it as an "algorithm" operating on various data objects.
If people get angry while reading this article, there must be some truth in what he says. Dissing OO is still swearing in the church.
I programmed for a long time not knowing OO and it was fine, there are other ways of encapsulation/isolation of code that works just as well. I don't really see that there's a big difference, and there's a certain element of religion about OO vs Functional. Both have their own merits in different types of applications. Still it's nice with someone who stands up for the functional approach.
OO and Functional are not the only two styles of programming out there. There's actually Functional and Imperative (and maybe others?), with OO being an additional concept that gets tacked onto both functional and imperative languages.
Von Neuman architecture sucks. From our educated and elevated point of view I think we can all agree on that. At least if we transcribe to "programming in machine language sucks". Perhaps one day we may elevate to agreement on "OO architecture sucks".
OO is a successful technology measured by what has been accomplished with it. The von Neuman architecture is even more successful. The one and only architecture behind all general purpose computers. But no sane programmer would touch machine code directly.
I have always thought that OO was wrong, in some sense at least. But I have to touch it. There is no higher and better level. There are alternatives but on the same level. So they suck in their own ways.
I remember when I started forming my mental pictures of what programming in the large was all about. How to think about it. How to structure it in my mind. I read Object-Oriented Modeling and Design by Rumbaugh et.al. Even if the authors didn't succeed in explaining it fully, I got the vivid impression, that they wanted me to believe, that a computer model should be structured along three dimensions: data, functionality and events. A space with a recording axis, data, an activity axis, functions, and a time axis, events. Though a somewhat fuzzy picture, I "saw" these three dimensions as orthogonal and of equal importance in structuring and building the complex structures called programs. I find OO to intermingle the data-function-plane but leaving timing in the cold. A skewed space.
I'm looking forward to the tools and technology, that will support my clean and "right" design model in a non-skewed concrete "code" space. Well, if they ever arrive, I might then have an even better mental model and find my self stuck with the new and better but sucking tools.
I'm sorry, this is way too thick of a block for me to read through. If you want a serious discussion of your idea, you might want to lay out your argument more carefully.
In an OOPL I have to choose some base object in which I will define the ubiquitous data structure, all other objects that want to use this data structure must inherit this object.
Obviously not if you use composition and if some objects are just your wrapper for your data structures.
Several comments have objected to this as if it were stupid:
In an OOPL data type definitions belong to objects. So I can't find all the data type definition[s] in one place.
The point is that OO programs consist of many type declarations scattered everywhere. As complexity grows, it gets harder to understand what all the types are and how they are related. The textbook "shape" and "animal" examples never come close to revealing this problem: they're oversimplified and they refer to things already familiar from the world. In other words they rely on OO's roots in simulation, where it works ok. In any complex system, though, you have to go far beyond ready-at-hand concepts. You end up declaring all sorts of arbitrary types that exhibit the problem Armstrong is talking about. There isn't even an easy way to see what they all are.
It gets harder and harder to change such programs because changing one type definition entails changing others. You can change how the internals of a class work (where it reduces to functions operating on private state), but significant overhaul of the class hierarchy itself is an order of magnitude harder than it should be (than it is in a program where you just have functions).
Armstrong's reference to keeping everything in a single file is not because he believes everything should be kept in a single file. That should be obvious, since he's obviously not an idiot. His point is how much easier it is in certain non-OO languages to understand a program's type system.
I think this is a valid criticism of OO because it cuts to the core of what people claimed was great about OO: that it helps to organize complex programs better and that it makes complex programs easier to change.
Edit: Armstrong is obviously smart, and Erlang is a real contribution, but it is also true that he is not a very good writer. I find he's the kind of writer that I have to make an effort to understand, which in his case is worth it because his intuitions are worth paying attention to. Of course not everyone need feel that way. But some of the comments in this thread seem a little knee-jerk to me.
Edit 2: Smalltalk is pretty clearly an exception to all of this. This has puzzled me for a long time. It just hit me maybe why: Smalltalk is actually not an OO language. Not in the sense we talk about OO nowadays. We've all been misled by the fact that it was the original OO language and that its creator introduced the term. Smalltalk's greatness comes from another place entirely, which is why no other OO language has equalled it.
...you really left us hanging there. Where does this supposed greatness-which-shall-not-be-named come from? The only distinguishing feature that I can recall about Smalltalk is that every operation is just passing a message--and that's certainly not unique among OO languages.
Absolutely true, which makes Joe's rants against OO rather silly. He's been bitten by bad OO implementations and closed his mind to the idea of OO even though he created a version of it with Erlang.
Erlang is a functional language specially designed (and suitable) for concurrent programming.
His rant is partially correct (at best), especially looking at OOP from a functional programming point of view.
However, developers in the real world who doesn't focus on concurrent programming have different needs.
I'll comment his objections from a C++ perspective (which is a multi-paradigm language, not purely OO):
Objection 1 - Data structure and functions should not be bound together
- you are free to store all your data structures in a single file, and access them from anywhere. However, using classes will let you hide some of the data structures which are not necessary globally, reducing the cognitive load.
Objection 2 - Everything has to be an object
- Not in C++. You use classes where appropriate, and ordinary functions elsewhere. I agree that everything shouldn't be an object.
Objection 3 - In an OOPL data type definitions are spread out all over the place.
- similar to objection 1. You CAN store all definitions in a single include file, but for large projects this can be a LOT of data definitions, where many/most of them are only relevant for parts of the applications. Hiding data definitions in separate classes will make it easier to focus on the RELEVANT data depending on which class/function you use.
Objection 4 - Objects have private state.
- again, similar to 1 and 3. "State is the root of all evil". If you store all data in a single file, then you have one giant global mess. By assigning them to a class, you clearly state the responsibility and scope of the variables. A private state is nobody's business but the class. You don't HAVE to have private state for objects,but then you either need to pass all data to each function, or use global variables instead.
For Erlang (functional programming) these objections make (some) sense since you DON'T want any state whatsoever to facilitate concurrency.
However, saying that OO sucks is stupid, and the four reasons for why OO was popular is not even worth responding to. I don't think functional programming will become more popular due to this rant....
I won't go so far as to say OO sucks, but I have noticed in my own code, that I have tended to use OO concepts a little bit and functional concepts a lot.
Over time, I'm using less and less OO and more and more functional, so... that tells me OO wasn't all it was cracked up to be.
The biggest problem I see with OO is that it doesn't map well to relational models and OO databases aren't that popular.
For once, just once, I would like to see someone compare apples to apples: OO vs corresponding encapsulation techniques in functional languages (abstract data types, ML-style modules/functors, Haskell-style typeclasses).
In case anyone was wondering, yes, the functional community loves namespacing, encapsulation, and creation of new data types with functions specifically intended for use on them.
The real question is: How do we express relationships between data types...
Do we use subtyping? (OO yes, functional no).
How do we allow multiple types to see each others privates? (Friends/inheritance in OO, modules in Haskell and ML).
How do we do polymorphism over static data/functions? (Basically, doesn't exist in OO... functors in ML and typeclasses in Haskell).
The immutability debate is another discussion entirely.
Isn't this rather like saying than since a five pound sledge hammer can't fix watches, tools suck?
I find it best to use the tool that is appropriate for the task. This is true even though you might be able to force fit a particular tool to a mismatched task. Saying that there is only one true way is always wrong. Especially since any of the ways we have are at best only good enough for some tasks, mediocre for many, and really horrible for others.
The title should be translated to "Why One True Ways Suck" or on a really bad day "Everything Sucks".
If the author wants to explain to us why he thinks OO sucks, that is a legitimate criticism, even if for some of us it would be hard to swallow. However, the fact that the author does not acknowledge the advantages of OO, (even if he believes they are less significant that the disadvantages,) is a good enough reason to ignore his criticism.
OO works becuase it roughly matches how we think. We see the world as objects at a basic level. As others mentioned, this makes coding more productive. It's a choice for the programmer, not the computer.
If you need really fast code, use assembler. You have that choice. Code at the level required for the task.
OO doesn't match the way I think anyway. OO makes it appear as if all objects can do something, e.g. window.open(), list.add(item). In the real world some objects are passive, some objects are active and conscious and some complex objects have behaviour but don't respond to simple instructions (e.g the economy).
I believe this is a very fundamental feature of how we think about the world and it's totally unlike OO. But I also think that it doesn't matter at all. Formal systems don't need to resemble language or the way we think about the world (or the way we think we think about the world)
We don't naturally think like Snoopy swearing, but regular expressions are still a very productive tool for someone who has learned to think differently than he would naturally do. The same goes for maths and many other tools.
I'm very skeptical about OO, but that's not because it doesn't match the way I think. I'm skeptical because OO APIs force me to know things I don't want to know. They constantly make me think about which class has a particular function.
But the rationale for putting a function in one class or another is based on implementation considerations that are of no concern to me as a user of an API. It's mostly about which object's state is affected most, how dependencies are managed, what types of changes are expected, and so on.
I've given this example elsewhere but here's the short version again: Say you want to initiate the sale of a property via some API. There are many objects involved: A buyer, a seller, a contract, an estate agent and a property. Which of the five classes involved contains the method you're looking for?
It could be in any of these classes and I don't want to think about it. I want a sell(property, buyer, seller, contract, agent) function and the API should figure out its own state and dependency matters.
[+] [-] visitor4rmindia|17 years ago|reply
* Data structure and functions should not be bound together
In some cases encapsulation works really well. For example GUI elements. It is less true for "process-oriented" components. But the arguments he makes don't seem very well thought out.
* Everything has to be an object
I actually agree here. To my mind, the biggest problem with OOPS is that is slowly devours all other concepts until we are left trying to force-fit all problems into the OOPS mould.
* In an OOPL data type definitions are spread out all over the place
This just ignorance.
* Objects have private state
This is also a good point. Having state actually tends to being a "bad" thing to do. Of course, the entire purpose of the object is to capture some invariant, but an object doesn't make that clear. Many objects contain instance variables that should actually be parameters.
* Why is OOPS popular?
Because it makes it easier and safer to get programmers working together as a group. The vocabulary of available objects is a simple and somewhat elegant way of communicating.
(EDIT: Corrected layout.)
[+] [-] ntoshev|17 years ago|reply
In a typical OO language all the code belongs in classes, and there is no way of telling which classes define the essential data types and which are mostly placeholders for code. There is no way to tell at a glance what are the important data structures. Just look at any open source Java project.
I use python and I find myself using more functions and fewer and thinner classes recently. In particular, if some state is transient, I find it is much better to keep it in local variables of the more abstract functions than obscure it as object state.
[+] [-] edw519|17 years ago|reply
Making OO the ultimate dogfood.
Whenever I encounter any kind of new "thinking", the first question I ask is, "Who is it good for?"
Ultimately, OO was made for us, not our customers. True, anything that helps us helps our customers, but I'd prefer to ask a more basic question...
If we have so many programmers that we need new technologies to work better together, are we doing something fundamentally too complex to begin with? Most of us aren't working on the space shuttle. We're doing relatively simple bread and butter apps moving data through logic. Before we surrender to OO, maybe we should take a closer look at why we need "easier and safer" ways to work together. For most of us, a simpler approach than OO often makes more sense. I suspect that's OP's biggest point.
[+] [-] jwilliams|17 years ago|reply
Additionally, he's run up against the pitfall with OO - it actually lacks a definition. It's got lots of dimensions and facets, and each implementation interprets these in it's own way... e.g You could argue that SmallTalk's message passing metaphor was the precursor to Erlang's model.
[+] [-] cabalamat|17 years ago|reply
There are plenty of OOPLs where this is not the case. For example C++ or Python.
> Why is OOPS popular? Because it makes it easier and safer to get programmers working together as a group.
That's true. But the main reason why OOPL is popular is because it makes programming more productive, whether there's one programmer writing the code or lots of them.
[+] [-] yters|17 years ago|reply
[+] [-] joe_the_user|17 years ago|reply
[+] [-] jamongkad|17 years ago|reply
Yikes guilty as charge here as I currently have a unhealthy fascination for the use of instance variables if not all in most of my objects. Thanks for the heads up.
[+] [-] gojomo|17 years ago|reply
The impressions I get are that Armstrong likes to stay close to a core set of raw data structures; he's more about the flows than the stocks; he finds delegation and specialization more frustrating than helpful; and he would rather build a combustion engine than an office building.
(He's probably an ISTP personality type at work but has put on his ISTJ hat for the purpose of writing this article.)
[+] [-] silentbicycle|17 years ago|reply
[+] [-] iamwil|17 years ago|reply
Nowadays, I sort of just use classes to scope and namespace. I keep state in classes when it makes sense.
To counter the point about state, Erlang programs do have state. They're just contained locally within a function. Since Erlang has tail recursion, you just call the same function recursively and pass the state variable you want to keep at the very end of the function for the lifetime of the program. Because it's tail recursion, there's no stack overflow. Also, Erlang threads can keep 'state' inside of the Mnesia database that comes with Erlang.
State is only evil when it's shared. Because state is contained locally in a function, a single Erlang thread can do whatever it wants, whenever it wants with those variables. Threads communicate through message passing. Therefore, no need for locks, mutexes or semaphores. Along with the low overhead of thread creation (~300 bytes) they're part of the reason why Erlang has great concurrency properties.
[+] [-] jrockway|17 years ago|reply
This is not true of "OO", it's just true of OO in languages like C++ and Java. These languages got OO horribly, horribly wrong; so if you use them and dislike OO, it's possible that you dislike the language -- not OO.
If you use CLOS, you'll see that functions are functions and data are data. CLOS just gives you some tools for calling different functions depending on the type of the data and for specializing subtypes. This is OO done right, and it is not what the author of this article is referring to.
Objection 2 - Everything has to be an object.
Everything has to have a type, yeah. But the line between "built-in type" and "object" should be blurry, and in CLOS it is. Again, if you are hating OO because of Java's implementation quirks...
Objection 3 - In an OOPL data type definitions are spread out all over the place.
I am not sure what the problem is here. Unless your code is all in one file, this is going to be a problem regardless of the programming "paradigm" you choose.
When writing Lisp, I often put all my class and method definitions for one chunk of the app in the same file. I think this is what the author wants to do, and it is do-able and commonly done in CLOS. In Java, yeah, you have to put each class in its own file. That is irritating, but the problem is not OO.
Objection 4 - Objects have private state.
This is true. I prefer to write OO code that maps one object to another, rather than mutating an object's internals. The sad reality is that this approach is slower and uses more memory than the mutation approach, but I think it's easier to reason about and maintain. Computers are fast, anyway.
So while it's possible to misuse OO, whatever that means for your particular tastes, it's also possible to not misuse it. If you hate OO, it is possible that you are doing it wrong.
[+] [-] omouse|17 years ago|reply
For Objection 2, well as you said, the distinction should be blurry. I really don't understand what his objection to Time being an object is. What Erlang is doing with deftype is basically creating a new "constructor" for an object that includes bounds-checking.
The problem in Objection 3 is that he's dealing with file-based languages (and so are you). If you use any Smalltalk, you'll find a nifty browser that organizes things by package name, and there are even categories for methods.
I wish people would stop posting ill-informed rants on Hacker News.
[+] [-] jcromartie|17 years ago|reply
[+] [-] access_denied|17 years ago|reply
[+] [-] mariorz|17 years ago|reply
I'm possibly damaged from a few years of OOP but how do you separate a data structure from its functions? e.g. How can a B-tree mean anything separate from its search/insert/delete operations?
[+] [-] visitor4rmindia|17 years ago|reply
For instance most examples on the net just assume keys to be long numbers but that is obviously insufficient for an actual application. Keys could be 20-bit hashes, strings, floats, doubles etc. The same applies to a lesser degree to the offsets (at leaf node level) and any embedded values.
Plus it is interesting that you view a B-Tree as an object - when I think about it, I categorise it as an "algorithm" operating on various data objects.
[+] [-] sunkencity|17 years ago|reply
I programmed for a long time not knowing OO and it was fine, there are other ways of encapsulation/isolation of code that works just as well. I don't really see that there's a big difference, and there's a certain element of religion about OO vs Functional. Both have their own merits in different types of applications. Still it's nice with someone who stands up for the functional approach.
[+] [-] barrkel|17 years ago|reply
[+] [-] jff|17 years ago|reply
[+] [-] jonsen|17 years ago|reply
[+] [-] jmtulloss|17 years ago|reply
[+] [-] Kototama|17 years ago|reply
Obviously not if you use composition and if some objects are just your wrapper for your data structures.
[+] [-] gruseom|17 years ago|reply
In an OOPL data type definitions belong to objects. So I can't find all the data type definition[s] in one place.
The point is that OO programs consist of many type declarations scattered everywhere. As complexity grows, it gets harder to understand what all the types are and how they are related. The textbook "shape" and "animal" examples never come close to revealing this problem: they're oversimplified and they refer to things already familiar from the world. In other words they rely on OO's roots in simulation, where it works ok. In any complex system, though, you have to go far beyond ready-at-hand concepts. You end up declaring all sorts of arbitrary types that exhibit the problem Armstrong is talking about. There isn't even an easy way to see what they all are.
It gets harder and harder to change such programs because changing one type definition entails changing others. You can change how the internals of a class work (where it reduces to functions operating on private state), but significant overhaul of the class hierarchy itself is an order of magnitude harder than it should be (than it is in a program where you just have functions).
Armstrong's reference to keeping everything in a single file is not because he believes everything should be kept in a single file. That should be obvious, since he's obviously not an idiot. His point is how much easier it is in certain non-OO languages to understand a program's type system.
I think this is a valid criticism of OO because it cuts to the core of what people claimed was great about OO: that it helps to organize complex programs better and that it makes complex programs easier to change.
Edit: Armstrong is obviously smart, and Erlang is a real contribution, but it is also true that he is not a very good writer. I find he's the kind of writer that I have to make an effort to understand, which in his case is worth it because his intuitions are worth paying attention to. Of course not everyone need feel that way. But some of the comments in this thread seem a little knee-jerk to me.
Edit 2: Smalltalk is pretty clearly an exception to all of this. This has puzzled me for a long time. It just hit me maybe why: Smalltalk is actually not an OO language. Not in the sense we talk about OO nowadays. We've all been misled by the fact that it was the original OO language and that its creator introduced the term. Smalltalk's greatness comes from another place entirely, which is why no other OO language has equalled it.
[+] [-] kilowatt|17 years ago|reply
[+] [-] richcollins|17 years ago|reply
- You can send them messages
- Their state can be mutated through receipt of messages
- They have private state
- Their functions are associated with the data that they operate on
[+] [-] gnaritas|17 years ago|reply
[+] [-] atlei|17 years ago|reply
His rant is partially correct (at best), especially looking at OOP from a functional programming point of view.
However, developers in the real world who doesn't focus on concurrent programming have different needs.
I'll comment his objections from a C++ perspective (which is a multi-paradigm language, not purely OO):
Objection 1 - Data structure and functions should not be bound together - you are free to store all your data structures in a single file, and access them from anywhere. However, using classes will let you hide some of the data structures which are not necessary globally, reducing the cognitive load.
Objection 2 - Everything has to be an object - Not in C++. You use classes where appropriate, and ordinary functions elsewhere. I agree that everything shouldn't be an object.
Objection 3 - In an OOPL data type definitions are spread out all over the place. - similar to objection 1. You CAN store all definitions in a single include file, but for large projects this can be a LOT of data definitions, where many/most of them are only relevant for parts of the applications. Hiding data definitions in separate classes will make it easier to focus on the RELEVANT data depending on which class/function you use.
Objection 4 - Objects have private state. - again, similar to 1 and 3. "State is the root of all evil". If you store all data in a single file, then you have one giant global mess. By assigning them to a class, you clearly state the responsibility and scope of the variables. A private state is nobody's business but the class. You don't HAVE to have private state for objects,but then you either need to pass all data to each function, or use global variables instead.
For Erlang (functional programming) these objections make (some) sense since you DON'T want any state whatsoever to facilitate concurrency.
However, saying that OO sucks is stupid, and the four reasons for why OO was popular is not even worth responding to. I don't think functional programming will become more popular due to this rant....
[+] [-] pj|17 years ago|reply
Over time, I'm using less and less OO and more and more functional, so... that tells me OO wasn't all it was cracked up to be.
The biggest problem I see with OO is that it doesn't map well to relational models and OO databases aren't that popular.
[+] [-] schtog|17 years ago|reply
[+] [-] jganetsk|17 years ago|reply
In case anyone was wondering, yes, the functional community loves namespacing, encapsulation, and creation of new data types with functions specifically intended for use on them.
The real question is: How do we express relationships between data types...
Do we use subtyping? (OO yes, functional no).
How do we allow multiple types to see each others privates? (Friends/inheritance in OO, modules in Haskell and ML).
How do we do polymorphism over static data/functions? (Basically, doesn't exist in OO... functors in ML and typeclasses in Haskell).
The immutability debate is another discussion entirely.
[+] [-] charlesju|17 years ago|reply
[+] [-] lgriffith|17 years ago|reply
I find it best to use the tool that is appropriate for the task. This is true even though you might be able to force fit a particular tool to a mismatched task. Saying that there is only one true way is always wrong. Especially since any of the ways we have are at best only good enough for some tasks, mediocre for many, and really horrible for others.
The title should be translated to "Why One True Ways Suck" or on a really bad day "Everything Sucks".
[+] [-] cool-RR|17 years ago|reply
[+] [-] jonke|17 years ago|reply
In the meantime read http://www.paulgraham.com/reesoo.html
Be neutral. Think. Could Joe have some valid arguments ? As someone said, patch your brain into Net Neutral.
[+] [-] ZamboniMan|17 years ago|reply
If you need really fast code, use assembler. You have that choice. Code at the level required for the task.
[+] [-] fauigerzigerk|17 years ago|reply
I believe this is a very fundamental feature of how we think about the world and it's totally unlike OO. But I also think that it doesn't matter at all. Formal systems don't need to resemble language or the way we think about the world (or the way we think we think about the world)
We don't naturally think like Snoopy swearing, but regular expressions are still a very productive tool for someone who has learned to think differently than he would naturally do. The same goes for maths and many other tools.
I'm very skeptical about OO, but that's not because it doesn't match the way I think. I'm skeptical because OO APIs force me to know things I don't want to know. They constantly make me think about which class has a particular function.
But the rationale for putting a function in one class or another is based on implementation considerations that are of no concern to me as a user of an API. It's mostly about which object's state is affected most, how dependencies are managed, what types of changes are expected, and so on.
I've given this example elsewhere but here's the short version again: Say you want to initiate the sale of a property via some API. There are many objects involved: A buyer, a seller, a contract, an estate agent and a property. Which of the five classes involved contains the method you're looking for?
It could be in any of these classes and I don't want to think about it. I want a sell(property, buyer, seller, contract, agent) function and the API should figure out its own state and dependency matters.