"Since functions and data structures are completely different types of animal it is fundamentally incorrect to lock them up in the same cage."
The conclusion doesn't follow.
"In an OOPL data type definitions belong to objects. So I can't find all the data type definition in one place. In Erlang or C I can define all my data types in a single include file or data dictionary. In an OOPL I can't - the data type definitions are spread out all over the place."
That's not true, you can create a file which contains all the types as interfaces.
"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."
You can implement an interface instead of inheriting a class.
In regards to the first quote, I find it helpful having both the data structures and algorithms in one "cage." I like having all relevant data in one easy to find location.
I agree, it's a family of closely-related implementation details.
You can also shrink the scope using visibility, get inherent namespace benefits for what would otherwise be loose functions, etc. The benefits are primarily organizational but organization in programming is a big deal.
I could be missing something but this seems like a strawman rant. Objects are not cages. In C, headers can declare structs and procedures next to each other because they in practice work together, so at least naming conventions should change simultaneously. OOP just took a design pattern and added it to language syntax. You can argue about the extremes to which this has been taken, but I don't see why the organizational pattern doesn't make sense.
These come up from time to time...I'm not saying they don't have some merit, but there isn't some "tyranny" of object orientation out there.
By OO I usually think of hierarchical taxonomy as an organizing principle and I find it very useful in lots of scenarios.
One thing that I loved about SICP was the way that they were able to explore all of these methodologies in a way where you could see them as variations of solutions over problems.
As with anything, "{insert-name-here} sucks" can be applied in plenty of scenarios. I consider myself competent in plenty of languages, including C# and Java. Recounting my experience with OOP languages, relative to the objections listed:
Regarding data objects to functionality: couldn't agree more, and that's why my data access libraries never contain anything of a functional nature within them. It's simply good practice, and makes for more maintainable architectures. Nothing about OOP prevents me from accomplishing this.
I've dealt with Date and Time objects plenty, and it turns out it's really no big deal. If you care about those things in terms of allocation to the heap and/or stack, there may be a point of consideration, but mostly it's just a matter of syntactical preference. It matters very little to any applications that I've participated in producing and maintaining.
Data-type definitions: the specific comment in the article refers to a location, as in a single file to locate data definitions. Again, this goes to code organization. Separation of concerns is good practice in many disciplines, and this is no different. If a person is sloppy with their code, it doesn't matter what type of language they use.
Private state: I'll refute the suggestion in the article that "OOP says to hide state." That's way too broad a brush stroke. The concept is encapsulation, and best practice says that the scope of state within an object refers only to itself. The article refers to system state, which is well beyond the scope boundary of a single object in OOP.
Again, these are all just tools to get a job done. How one uses the tool is the most important consideration.
FYI, this is Joe Armstrong (the creator of Erlang)'s rant on OO.
It's a pretty shallow article with hardly any substance that was written more in reaction to the fact that nobody is (was) paying attention to Erlang than an informed criticism of OOP.
How unfortunate then that this is the first negative feeling I have in relation to Erlang. I've actually had limited but good experience with ejabberd, and everything else I've encountered was positive.
OOP isn't perfect, but I don't think this post addresses any actual problems.
> Since functions and data structures are completely different types of animal it is fundamentally incorrect to lock them up in the same cage.
That's one way of looking at it, but definitely not the only right one. OOP implies that there are objects, just as in real world, that can act by themselves, on themselves (or, in rare cases, on others). I can't really see how `user.addPost(post)` or `file.append(str)` is inherently wrong. By the way, what would the "FP way" of expressing this be?
> In an OOPL data type definitions are spread out all over the place
Because data type definitions are secondary to class definitions. It's how the paradigm works. You don't think about data types, you think about how classes interact with each other.
> Suppose now I want to create some "time" object, where does this belong and in which object
> OOPLs say "hide the state from the programmer". The states is hidden and visible only through access functions.
That's not what OOPLs say at all. The state of an object is "hidden" from other objects, but programmer should have no problem accessing it (hopefully their IDE will help).
I'd also like to see how the author tackles UI programming in a stateless paradigm, let alone any performance-intensive tasks (for example, rendering in a real-time game).
Whilst I am not an OO fan per se, I found a lot of these objections quite weak.
-- Objection 1 --
Nobody claimed that functions and data structures are the same thing. However, I still keep my toothpaste with my toothbrush. You have not explained why keeping them together is bad, except for the suggestion that different things should not be put together.
As an example of different things that should be kept together, I suggest functions and their type specification.
-- Objection 2 --
You have not stated what's better about the Erlang approach, just that it is different. As it stands I can reverse the wording and it means largely the same thing:
"""
Consider "time". In a non OO language "time" hat to be an instance of a data type. But in an OO language "time" is an object. For example, in <OO Language> there are lots of different varieties of time, these can be clearly and unambiguously specified using class declarations, as follows:
<code>
Note that these definitions do not belong to any particular data type. they are ubiquitous and objects representing times can be manipulated by any function in the system.
There are associated methods.
"""
-- Objection 3 --
"In an OOPL data type definitions belong to objects. So I can't find all the data type definition in one place."
Although I agree with you, there is the converse that in a non OO language the reverse is true. Why is one better than the other?
"As lisp programmers have know for a long time"
That's an argument to authority. Why do they belive that?
"A ubiquitous data structure is something like a linked list"
A good number of OO fans would criticize you for saying that.
"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."
This is false. Although inheritance is a decidedly OO tool, it is not the be-all and end-all of OO. Have you really never seen a Java List as a member or local variable?
-- Objection 4 --
"Pure declarative languages say that there is no state."
This isn't true. What would you say a datatype is, if not state? All these languages do is separate state, not remove it.
"The "hide the state from the programmer" option chosen by OOPLs is the worse possible choice."
Why? Again, you have asserted something to be true that an OO advocate would disagree on. This makes for a weak argument.
I may believe in many ways Erlang is an evolution to Smalltalk, a better way to program. But I read Kay and it feels like an educator talking, explaining the reasons for some decisions. I read this and it comes across as bitter rant about why my favorite language didn't get popular. Kay's Smalltalk was never popular either. This argument preferring Erlang might be right at its core, but it's hard to get past the bits of the argument presented that are petty or plain wrong.
Objection 1 - Data structure and functions are bound together
Objection 2 - Everything is an object
Arguably OO is a shorthand for enabling two things:
- message passing based on function signature
- a given data structure as the first argument ("this")
The message passing thing, Erlang handled a different way through the actor model, one that took concurrency in mind which was not in Smalltalk's early objectives. Erlang is arguably a better way.
However I (just me; probably not alone) originally found it hard to understand some Erlang programs because it's a pile of functions - the patterns and protocols against the data structures are all subtext and one needs to read a lot of example code to grasp them. Whereas objects and interfaces make the message passing protocols pretty clear, only a couple examples and I get the message.
One of the major nuances of OO and Smalltalk was that the language was only half of the story, Smalltalk was also a runtime and IDE, that made browsing and modifying code a joy. The image based approach has a ton of drawbacks compared to text files, of course, but now there are plenty of Smalltalk-like IDEs or code-browsing friendly text editors for both OO languages and functional languages such that anyone should be able to "suck it up" and follow the call chains and interrelationships.
Objection 3 - Data type declarations are all over the place
This seems subjective depending on the language, and even just wrong. Inheritance isn't required to reuse a data structure, OO design prefers composition. Most classes are composed out of fundamental data structures that are located in a well defined package.
Objection 4 - Objects have private state
Alan Kay agreed that mutable state is the root of all evil, or as he says, "assignment is a metalevel change". This is why he made state private!
I'm not sure what his point is here, as when you need shared mutable state in Erlang, you build an Actor to maintain and HIDE the mutable state. Which looks a heck of a lot like an object.
The conclusion doesn't follow.
"In an OOPL data type definitions belong to objects. So I can't find all the data type definition in one place. In Erlang or C I can define all my data types in a single include file or data dictionary. In an OOPL I can't - the data type definitions are spread out all over the place."
That's not true, you can create a file which contains all the types as interfaces.
"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."
You can implement an interface instead of inheriting a class.