
No, that's not why OO sucks - johndcook
http://www.librador.com/2012/07/16/No-thats-not-why-OO-sucks/
======
fusiongyro
As time goes on, my bafflement at our collective need to swear allegiance to
our tools is turning into bewilderment. Our tools have objective, technical
merits and flaws, but our love and hate for them is subjective and mostly
useless. Cargo cult behavior is the real problem, and the endless bickering
and correcting that articles like Joe's and this one contain only serve to
perpetuate it.

~~~
cdmckay
I don't think the author was loving or hating OO, he was just pointing out the
Joe Armstrong's points weren't very well argued. It's not bickering, it's
discussion, and it helps people to understand the paradigms better.

~~~
sukuriant
I believe the commenter was talking as much about the person OP as he is the
OP's cited article.

~~~
Ralith
Is the author of this article known for being religious about paradigms?

------
glassx
I really don't know why people seem to think that post is the _final_ position
of Joe Armstrong about OOP. It's a very old post, without any context, and
since then he has gone on record praising Smalltalk and Alan Kay's take on
objects many times:

<http://infoq.com/interviews/johnson-armstrong-oop/>
[http://erlang.org/pipermail/erlang-
questions/2010-August/052...](http://erlang.org/pipermail/erlang-
questions/2010-August/052836.html)

------
AndrewO
I think the author and Armstrong have significantly different ideas of what a
"type" is. That's not a huge surprise—depending on background, you'll often
get several definitions from different people.

One way to see types are things with fundamentally different access pattern:
individual entities, sequentially retrieved ones (e.g. lists), fixed-length
ordered lists whose elements are accessed positionally (e.g. tuples/vectors,
fixed-length maps whose keys are known at compile-time/records/objects can
also be viewed this way), unordered collections of distinct entities (sets),
etc. I'd argue Armstrong's view is similar to this based on what he put in
Erlang.

I can't tell what the author's view is, aside from "a class is a data type".
This suggests that he equates a type with the set of functions that can be
called on something and not have the compiler or runtime blow up (or perhaps,
the set of functions that the programmer, by putting them in the same file,
has explicitly said won't blow-up, whether or not that set is correct or
complete). This throws fundamentally different things like lists, tuples, sets
onto the same level as Person, Account, and PayrollRecord—which are often just
short-hand names for tuples with different arities or names for their
elements' positions.

If one has the later view, confusion over the point 3 is understandable:
creating a new type for time is easy, just do class Time and define a bunch of
properties and methods. In Armstrong's example, time is just a 6-tuple (or
3-tuple if all you want is hms). If you wanted to store it or send it over the
wire, anything that could handle a tuple of integers would already know how to
use it. If one function calls the last member "sec" and another "second",
they're local names, so it doesn't matter as long as they're both accessing
the same member.

One can object that it's easy to write serializers or that a compiler or
library could figure it out, or that having different names for the same data
elements indicates inconsistency in code that should be caught earlier. De
gustibus non est disputandum. But, don't throw up your hands and say "this
makes no sense!" without considering another perspective first.

~~~
artsrc
I propose that making the position of hour, minute and seconds the canonical
definition is worse than using their names.

So this: { type: "hms", hour : 10, minute : 45, second : 16 }

is better than this:

    
    
      ["hms", 10, 25, 16 ]
    

Either go across the wire fine. The names are not just local names, they
describe the meaning of the data.

In the JavaScript world we would call the map an object.

------
shin_lao
Objection 1: The OP should take a look at the STL.

Coupling N algorithms and M structures may lead to M * N implementations where
you really want only N + M implementations.

Additionally, decoupling algorithms and structures will probably make you
write better interfaces for your structures.

~~~
Fargren
But that's just because of bad programming, not because of OOP, I think. I
mean, of course you can use OOP to make really crappy designs, but
polymorphism should make you able to have N+M implementations and not M*N.

~~~
evincarofautumn
(Static) polymorphism is the very thing behind the STL. In order to decouple
algorithms from data structures, you need a standard interface between them.
In the case of the STL, that interface is iterators; other interfaces (such as
stacks or ranges) are also possible, and in my experience much nicer to work
with. But none of it _requires_ OOP.

~~~
Fargren
Well, of course OOP isn't _required_ for a good design. What I'm saying is
that, as far as not redefining functionality for different types, it doesn't
work against it. At least not if we allow for static polymorphism, and I'm
pretty sure that's considered an integral part of object orientation; at least
I remember Kay talking about it.

~~~
evincarofautumn
Static polymorphism wasn’t part of OO originally; in Smalltalk, everything was
late-bound. And you can of course write things generically even in the
“classes and methods” kind of OO, but I think the culture around that paradigm
encourages coding non-generically. You might say OO itself works toward
genericity, but some OO-branded languages work against it.

------
greghinch
I've noticed a pattern with people who rally against OO, that when you get
down to the core of their argument and what irks them, they really just don't
like Java, with all its superfluous-feeling ceremony code. Maybe try a lighter
OO implementation first before you decry an entire methodology.

~~~
ww520
Why do Java invoke such a strong negative emotion from people? It is not like
a gun put on the head to make them use it.

~~~
eropple
Because a lot of people have been exposed to Java, and a lot of people have
been exposed to bad Java. There's not a lot of "good Java" (at least that I
know of) that's publicly available for reading and understanding. Couple that
with the infuriating environment (whoever came up with the 'application
server' as exists in Java EE should just feel _terrible_ about themselves) and
it's easy to see why it gets people's hackles up.

Me, I don't mind Java so much, but the loads and loads of ceremonious bullshit
that Java forces upon me is annoying and I absolutely despise web development
in any of the existing tools[1]. I'd love something more friendly for what I
do. (I would punt many adorable helpless kittens for a working C# on the JVM.)

[1] - Please don't reply to this to tell me I need to try Play. I have. It's
not much better to work with, its developers are absentee and don't seem to
want outside contributions, and it has no community to speak of. Not good.

~~~
pjmlp
The problem is that this is not Java specific, rather enterprise specific.

Before Java EE, I was coding similar type of applications with CORBA
frameworks, and before that RPC frameworks.

Now I am doing .NET, and we have to use a Java EE like framework as well.

Enterprise architecture has a Midas touch to make everything complex.

~~~
eropple
That's definitely true, but when you say "Java", most people _immediately_
think "Java EE", and that for things that should be simple (like a blog web
app), you're forced into "enterprise" stuff.

It's largely cultural (and though they aren't doing a great job the Play guys
should be commended for trying), but no less a problem.

------
aidenn0
A better "functions should be separate from objects" is for the fairly common
case where there is a function that takes arguments of two (or more) different
classes as arguments; which class should that belong to? It gets even worse
when the function is commutative.

~~~
MichaelSalib
Isn't that what multimethods are for? Multimethod systems (like CLOS in Common
Lisp) allow you to specialize methods based on the types of more than the
first argument.

~~~
aidenn0
Yep, but in CLOS, methods don't belong to a class, which is different from
what most people mean when they say object oriented.

~~~
MichaelSalib
Once you have multimethods, you don't need to couple the method definitions to
the class body. But you're still doing object oriented programming; CLOS is an
object system. The fact that people assume that OOP==Java is unfortunate, but
doesn't change the fact that CLOS is also OOP.

Beyond that, I think you're conflating how method bodies are placed in a file
with "belonging to a class". I can define C++ methods outside of the class
definition, but surely no one would say that such methods don't belong to a
class.

~~~
aidenn0
Well if 95% of the population use a term to mean one thing, then arguing that
no it really means something else doesn't get you anywhere.

And no, I'm not conflating those. In C++ and Java, classes are, among other
things, namespaces. When you declare a method in a class, it ends up in that
namespace. Where it is defined is unimportant.

~~~
batista
> _Well if 95% of the population use a term to mean one thing, then arguing
> that no it really means something else doesn't get you anywhere._

It's not about getting "somewhere". It's called computer SCIENCE, remember?

~~~
aidenn0
When someone says "object oriented" unless they define their terms, or are
clearly coming from the smalltalk school, I assume they are talking about
C++/Java style OO, since that assumption is right the most often.

This is particularly true when someone is talking about "what's wrong" with
OOP

------
pfraze
Not sure where I sit on the issue, but I wanted to add this:

By putting the functions in the class definition, they become locked into that
class. Other data structures could potentially make use of the function, but
now they don't own it. I would say the alternative is a namespace, which you
don't instantiate.

Armstrong's grief is the idea that the functionality for classes can then only
come from direct lineage. As I understand it, though, the OO-heavy languages
(Java, C#, probably others) lean much more heavily on interfaces now to mix in
behavior, which gets away from that specific problem.

[EDIT] I forgot that interfaces don't give implementation, so the mixing is
pretty limited.

Not sure what I think of the state issue, though. Too green on the functional
stuff to say how else it should work. I would point out, though, that programs
hide state from each other; couldn't objects just be the same thing on a
smaller scale? (That is, an opaque interface with a few access points.) It
really comes down to how well it's made in both cases.

~~~
anonymoushn
Java doesn't have multiple inheritance, so if you want to avoid writing the
same behavior twice you instead get to write several interfaces describing the
ability to do the behaviors and write several functions in each class that
implements such an interface (but does not contain the implementation) calling
the functions defined in the interface on its pet InterfaceImpl.

This is probably a worthwhile tradeoff, but checking in hundreds of lines of
code that do literally nothing is still a bad place to be.

~~~
pfraze
Ah, that's right-- interfaces don't give implementation. So yeah, Armstrong's
criticism stands.

~~~
UnFleshedOne
In C++ they do. In C++ anything goes. <insane laughter>

------
guelo
I think in practice most OO programs end up with two general kinds of classes.
Some are more for data structures, e.g. User or Address classes, and others
are more for functions like IOWriter or DAOs.

But there aren't strict dividing lines between these two types, you end up
mixing and matching functions and data as you see fit to help organize things.
So you might put state into your function classes, such as the DB connection
in a DAO:

    
    
      db = DBGetter.get("serverAddress;dbName;username;password;")
      userDao = new UserDao(db)
      User user = userDao.getUserById(123)
    

You might also end up putting functions in your data classes, but you might
not. As an example, to calculate the distance between two addresses you could
put the function in the Address class:

    
    
      float miles = address1.distanceTo(address2)
    

Or you could create a DistanceCalculator class that mostly just holds
functions:

    
    
      float miles = distanceCalculator.distanceBetween(address1, address2)
    

There are pros and cons to either design, personally I would go with the
second one, but the point is that you have a choice. OO provides a flexible
framework and there are many ways to design your classes. That's why there are
a bunch of books on OO patterns and best practices, to help design the
structure of classes. You can even work in a very functional/stateless style
if you want to.

What OO gives you are tools for organizing your code but you can organize in
many ways, some ways that help and some that hinder. As others have said, it's
just a tool.

~~~
klawed
The use of ORMs should/does eliminate the need to write any of the data
structure classes. They still exist but they're automatically generated and
updated. And the use of your second implementation allows you to separate your
state from your business logic.

------
MatthewPhillips
> The basic idea of OO is that data and functions are bundled together, which
> is an idea that Armstrong seems to hold a grudge against (objection 1). But
> he gives no arguments as to why this is a bad idea.

Code reuse. Functions that are tied to a data type are less likely to be
reused, and if you find that you want to reuse one it will, a lot of the time,
require major refactoring (perhaps you have to move the function to a parent
class, or create an entirely new class that represents the thing that is
common between this data type's use and other data types' use of the
function).

Whereas if your data and function are never coupled you actually wind up
writing more generic functions that don't care about the type they are
operating on.

~~~
ww520
OO doesn't prevent the use of pure function class. You can group all your
common util functions together into the util classes.

OO really isn't dogmatic in forcing one style or the other.

~~~
MatthewPhillips
Utility classes are code smell (paradigm smell, even). They exist where the OO
model breaks down and you want to get-shit-done rather than spend an hour
thinking about where you can stick function X so that it's useable by class Y
and Z. Same goes for verb classes; you know, those does-the-thing classes that
you create which are just objects wrapped around a single function called
execute(), run(), create(), etc. etc.

~~~
ww520
Utility classes serve merely as organization purpose. It has nothing to do
with OO. It's like putting related files in a directory, or putting related
Python functions in a module.

I don't get how "stick function X so that it's useable by class Y and Z" is
relevant for consideration. As the name suggested, utility classes are
function libraries that can be used by all.

~~~
wonderzombie
The problem is that what you "really" want when you're doing this is a plain
old namespace. In some languages, objects necessarily come with a bunch of
baggage and implications you don't want without some way to opt out.

Yeah it works fine most of the time, but it's a bit like the opposite of
primitive obsession. You wouldn't use an Integer class for an index in a for
loop.

In Java you have little choice but to dump it all in one place. Contrariwise,
Python offers you more options; you _can_ just make a module and put a bunch
of top-level methods in there if you want. Go has some notion of "objects" but
you can have methods or top-level functions in a given package. And so on.

~~~
ww520
No, the problem is not to use a namespace. The problem is I want to organize
related functions as a group. Namespace is just one way to do it. There are
other ways. Package, class, namespace, or module serve the same function in
term of organizing functions.

What are the bunch of baggage and implication to use class as a way to
organize functions?

I don't see the difference in usage you mentioned with Python module. Putting
a bunch of "top-level" methods in a module is the same as putting a bunch of
static methods in a class.

------
sbmassey
OO is a good fit for programming a lot of important types of software, such as
GUI's or 3D graphics, where it is convenient to model the program data as
consisting of widely different types of data structure, having a common
interface, and which are easy to add new types to without having to change
existing code.

Other than that, most use of OO is really just applying the language's OO
structures to software idioms that exist outside OO, such as modules, or data
hiding, or closures, and so forth.

The only times OO actively sucks is when you're trying to do non-OO stuff in a
highly-OO language, such as trying to do algorithmic code in Java.

------
pjmlp
I think that most people that bash OO fail to understand how to use it
properly.

From my experience many are also pretty bad at doing ADTs in module based
languages.

OO has quite a few powerful concepts, and not all languages that are OO based
explore the same set of concepts.

This is why the best languages to work with, are the ones which offer multi-
paradigms, allowing the developers to pick the best abstractions for each
scenario.

~~~
it
I bash it not because I don't know how to use it but because I see if being
used so often for jobs that would be better done using other techniques.

~~~
pjmlp
Why blame the technology, when the real problem was the person that made the
decision to use it?

------
ww520
I don't get how state being evil. Pure functional program also has state. Its
state are the arguments passed around between functions.

What people talk about the evilness of state really is the scope of the state.
In a typical program, there could be global state in global variable, local
state in function local variable, and the state passed around in function
parameter. OO adds the instance level scope state for instance variables.

All these different levels of scoping are tools for programmers to manage the
complexity in a program. If you don't like global scope, don't use it. If you
don't like instance level scope, don't use it. Pure functional code are NOT
appropriate 100% of the time. A global variable can be simpler and cleaner to
get the job done. There are times for different tricks in a toolset. Use the
right tool for the right problem.

edit: added the NOT. Bad omission completely changed the meaning.

~~~
rbanffy
I like to joke that, if your program executes without any side effects, how
can you prove it did? ;-)

~~~
sbmassey
You can look at it's return code.

------
halayli
I find it funny that programmers are debating why we should hate OO. It's like
we know we should hate it but we are still in progress of figuring out why.

------
blahbap
The title suggests that the aurhor will provide reasons for why OO actually is
bad, but he doesn't. Why is it so fashionable to bash OO anyway? It's just a
tool, it can be used wisely, but often it is not, which gives no reason to
blame OO.

~~~
aero142
OO is not "just a tool", because it's often coupled with a language. A wrench
is "just a tool" because I can always reach over for my socket set if that
seems to fit better. Once I'm in Java, I am locked into a whole ecosystem and
Java work hard to make sure you write OO code. I can't just reach for a lisp
halfway through if I think that tool would work better.

~~~
fauldsh
Are you saying no project can consist of multiple languages working together?

~~~
aero142
No, but I am saying that switching between them is not as easy as grabbing a
different tool. The easiest place to switch languages is between abstraction
layers or between functional components/processes. These language separations
do not often coincide with the types of code that benefit from either OO style
structure vs functional data processing.

------
joelthelion
OO doesn't suck, it's just a tool among others in the toolbox. What sucks is
making a religion of it.

~~~
MichaelGG
This is a rather lazy argument I often see levied. It provides no real
insight, and defends against everything equally. "Gotos are just a tool; On
Error Resume Next is just a tool; null pointers are just a tool; etc."

That said, I think Joe's original article against OO was ill-informed (which
is surprising, given his status), and this article rightly points out that
Joe's arguments are bogus.

I don't think anyone disagrees that religious battles are stupid. But to sweep
all discussion about tools under the "hey man, different tools for different
jobs" just avoids critical thinking. If you don't want to participate in these
discussions, don't. It's like a discussion on Windows Phone 7 UI, and someone
comes along and says "lol, doesn't matter, Windows Phone 7 will never take
off".

------
zwieback
Anyone participating in these types of discussions should start with a
disclaimer whether they are talking about static typing, where types are
largely equated with classes (aka "class-based" programming), or message
passing, where types are largely orthogonal to classes.

The latter concept is what Alan Kay had in mind when he "invented" OO although
arguably C++ and Java have really popularized OO as class-based programming.

~~~
Ralith
Static typing is orthogonal to, although not generally paird with, message
passing. You can have dynamically typed Java-style OO easily.

------
malero
OOP is just another tool in my toolbox. It makes a lot of sense for some
problems, and none at all for all of the rest.

------
shimsham
Which is what makes PHP so good, as you're not forced to use any particular
style of programming. Or C.

~~~
flyinRyan
And, dutifully, most PHP programmers don't bother using any particular style
of recognizable programming. When in Rome...

------
ajuc
Ad 4 I don't see how you can do OO without state.

------
sodelate
OO,really matters

