
I laugh at your puny human 'objects' - gdp
http://plsadventures.blogspot.com/2009/08/i-laugh-at-your-puny-human-objects.html
======
raganwald
I actually agree with the Author's issues around hidden mutable state. Luke
Galea introduced me to the term "Candy Machine Interface" for this, where you
keep pulling levers and pushing buttons and you have no idea how to get the
candy you want out of the machine.

I also agree that the "real world" does this some times, but there is a
difference between writing simulations of the real world and writing programs.
I'm not disturbed by the idea of objects encapsulating hidden state, but
rather the idea that objects have static, invariant interfaces.

One of the nicer ideas for dealing with this is to write explicit state
machines and where (if your language allows) the interface actually changes as
the state changes. If o.a(); o.b(); is different than o.b(); o.a();, you can
write a state machine that makes this inspectable and explicit. If o.b() makes
no sense until you call o.a(), you can simply not have o.b() be part of o's
API/interface until you call o.a().

I won't suggest this is a general programming heuristic, but my experience in
the last couple of years is that every business object modeling a real-world
business entity ought to be implemented as a state machine until you discover
a compelling reason to do something else. Ad-hoc state machines, like having
the logic for whether o.b() does x or y based on the contents of fields _a and
_b be embedded in the method b() are the stateful equivalent of spaghetti-
coding with GOTO.

I credit Pete Forde for shaking me out of the complacent belief that I'm smart
enough to embed everything in methods.

~~~
wwalker3
This is a mind-blowing and cool idea as others have said, but the idea of an
object whose methods change depending on their internal state is a bit
counter-intuitive.

Real-world objects don't have this property -- it would be like the gas tank
hatch disappearing from my car after I fill it up, and reappearing once I
drive around for a minute.

~~~
raganwald
Real world objects don't have this property?

Some do. When the gear shift lever on my Mazda is in one of the automatic
slots, you can't upshift or downshift manually.

In business this is even more obvious. Contracts might have states: proposed,
drafted, agreed, signed, and so forth. You can't sign a draft, it has no
meaning. That's part of the business process.

~~~
wwalker3
Not quite the same. Your Mazda shift lever's manual slot doesn't disappear
when you're in automatic. You can still sign a draft contract, it's just not
binding.

In the software case you explained, the interface changes so you can't even
_try_ to do the wrong thing. On real-world objects, you can always try to do
the wrong thing, it just doesn't work.

~~~
raganwald
You cannot sign a draft, signing is a legal thing, not just a putting your
name on a piece of paper thing. Imagine you're a manager and you call your EA:
"Henderson, get me the YC contract to sign!"

Henderson replies back on the squack box: "Sorry sir, it's still a draft, it
has to be approved by legal before you can sign it."

> Your Mazda shift lever's manual slot doesn't disappear when you're in
> automatic

No it doesn't, but you can't actually move the lever there without changing
the gearbox's state from Drive to Manual.

So, we can say that it has an interface including the messages "+" and "-" at
all times (The slot), but there's no way to send it a "+" or a "-" message
unless the gearbox state is "M."

------
wwalker3
The author's objection to data encapsulation seems to be that for an object X,
the internal state produced by "X.a(); X.b();" may be different from that
produced by "X.b(); X.a();".

But this behavior is exactly what makes an object. Programmatic objects are
supposed to be analogous to real-world objects. If I shift my car into first
gear, then turn the key to start the engine, I get very different results than
if I do the reverse.

Even abstract mathematical objects like vectors and matrices work this way. If
I rotate a 3D vector twice, the final direction it points depends on the order
I do the rotations in.

~~~
gdp
Your examples ignore the way that data encapsulation is used though. You can
inspect the position of the gear lever in your car before deciding what to do
next. A vector rotation relies on no external state whatsoever.

A better example would be if you had a counter hidden somewhere out of sight
which counted the number of times you turned the key in your car, and
introduced different behaviours for key-turning based upon that value.

~~~
algorias
Ok, so you've proven that an OO design can be badly thought out, which is also
true of every other programming style.

------
amalcon
I know it's popular around here to dislike OOP, but this guy's main objection
is to mutable state. Analogous situations can occur in an imperative paradigm
without objects.

You can easily make use of OOP with no mutable state. You don't get some of
the features of OOP, but you can still leverage inheritance in interesting
ways.

The other main objection is that OOP isn't a good model for all domains. Don't
tell the OOP zealots I said this, but you don't have to use OOP when it
doesn't model your problem well. Nobody forces you to use object-oriented
techniques. Even if you're stuck with Java, you can just declare a bunch of
static methods, and suddenly your "class" is a "module".

It's a tool, and like any other tool, it shouldn't hurt to have it in your
box. Just remember to take it out only when it will help you.

~~~
apotheon
> I know it's popular around here to dislike OOP, but this guy's main
> objection is to mutable state. Analogous situations can occur in an
> imperative paradigm without objects.

To be fair, the guy's one reference to imperative programming made it sound
worse than OOP.

~~~
amalcon
Imperative and object-oriented are on different axes. OO is an organizational
paradigm, while imperative is an algorithmic paradigm. It's not hard to
conceive of a more declarative object system.

~~~
apotheon
Agreed. That doesn't dispute what I said, though.

------
tjic
_X.a() then X.b() may be completely different to X.b() then X.a(). This
implied ordering is not really expressed anywhere._

Oh noz!

OO is capable of CORRECTLY modeling complicated real life objects like Rubik's
Cubes, cars, clothes, and vending machines...

Why is it a failure that depositing $100 to a new checking account, then
writing a $90 check does a different thing than writing a $90 check against an
empty checking account, then depositing cash after the check has bounced?

~~~
apotheon
I think the problem the author has (but fails to articulate well) is that the
variance in consequences of doing things in different orders is not explicit.
In short, it's like you are never allowed to know what the balance of your
account is until you overdraw it.

Of course, I'm not sure whether that's a valid complaint either, since one can
always define accessor/getter methods (e.g., "get_balance" for the checking
account), but there are those who would argue that accessor methods violate
the data protection principle of object oriented programming.

------
alaricsp
I agree with some points and disagree with others here.

I think I see three underlying problems:

1) Mutable state has consequences, and OO happens to highlight some of them

2) The author would probably prefer generic functions, the "other way" to do
OO IMHO, as they give you polymorphism while leaving the encapsulation issue
to other mechansism, such as modules, as they mention.

3) OO examples are just terrible. Who on Earth writes a Bike class? I've seen
whole arguments about whether Car should inherit from Vehicle and all this
rubbish, all because people are taking vague and non-realistic examples, then
getting tangled when they try and realise them. This is a road sure to lead to
meaningless discussions and confusion on the parts of students. Instead, let's
think about real software objects, such as files, windows, threads, and
connections; and problem-domain objects such as users, orders and so on (as
long as one is gently aware of the subtle issue that a 'user' is a person
while the 'user' in the system is an object that models a person). OO can work
well for modelling such objects.

~~~
gdp
> _Who on Earth writes a Bike class?_

[http://java.sun.com/docs/books/tutorial/java/concepts/inheri...](http://java.sun.com/docs/books/tutorial/java/concepts/inheritance.html)

<http://www.novio.be/blog/?p=621>

<http://www.roseindia.net/software-tutorials/detail/9172>

The 'Bike' is a very common example used in OOP texts, hence why it was
included in this discussion. I agree that it's kinda terrible, but this is the
common textbook way that OO is described.

~~~
kragen
Terrible textbooks aren't evidence that object-orientation isn't a useful
style. They're evidence that it's popular and not trivial to understand.
That's evidence that it _is_ useful. Your post is more evidence that it's
popular (since you're bothering to write about it even though you don't like
it) and not trivial to understand (since you didn't bother to mention any of
the important aspects of it).

------
Quarrelsome
He's kinda missed the point of simplification you get from encapsulation.
Encapsulation makes the API smaller and more manageable. If I want to ride a
bike I don't want to have to worry about the internal workings. I just want to
use the Pedal() method. Sure, if that throws a FallOffBikeException I might
use more of the API to examine the problem. However I don't need an API that
tells me everything, such as the chemical composition of the metal used in the
frame. For his gravity he also probably wants to outsource that to some sort
of gravitatonal context that is supplied externally as opposed to including
the physics in the bicycle. I'm pretty sure that in computer games they don't
put the physics in the model code. :D

And btw, points in .NET (omg OOP!) are immutable structs so i'm not sure why
he thinks everyone should make them a class.

------
seregine
When writing a program, you usually don't model the Platonic ideals that make
up the universe, with perfect encapsulation. You model aspects of the world
relevant to the problem you're solving. You give them shorthand names that
make sense in the context of the program, not in the infinite real universe. A
Bike class in an ecommerce app means something different than a Bike class in
a bike-racing video game. Reusing the ecommerce class in the game context is a
silly requirement.

Instead of "hiding", think of encapsulation as "organizing". You can organize
verbs, most of the time, by the parts of program state they deal with. There
are multiple reasonable ways to do it. That's what makes object modeling a
more flexible tool than you give it credit for.

~~~
dasil003
Hm, I'm not sure about that. The thrust of the argument seems to be that
object orientation conflates state and behavior far beyond the point that it
is useful--that things end up getting shoe-horned into objects where it
doesn't make sense just to satisfy the paradigm. I think there's definitely
something there even if the rant is a little over the top.

In my opinion OOP took off because it's such a natural fit for GUI programming
and then everyone just started thinking that way. It's natural to think about
data types and the functionality that goes along with them, but I don't think
you need to go nearly so far down the path that recent languages have taken in
order to satisfy that association.

~~~
seregine
Sure, it's just another tool, but OOP is not Java. The original post said
"objects are a bad way of modeling the universe."

~~~
dasil003
My comment is not specifically about Java. I really think there is a limit to
the usefulness of fusing all data to the code that operates on it. I'm not
religious about it or anything, I think it's just something that bears
consideration in today's software ecosystem.

------
dkersten
Sounds like he wants "Entity Systems" (as defined by how game developers use
the term).

[http://cowboyprogramming.com/2007/01/05/evolve-your-
heirachy...](http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/)

[http://www.gamedev.net/community/forums/topic.asp?topic_id=4...](http://www.gamedev.net/community/forums/topic.asp?topic_id=468572)

[http://www.gamedev.net/community/forums/topic.asp?topic_id=4...](http://www.gamedev.net/community/forums/topic.asp?topic_id=489703)

[http://didntread.wordpress.com/2009/07/14/building-a-
stackle...](http://didntread.wordpress.com/2009/07/14/building-a-stackless-
hierarchy/)

------
kragen
Gian,

If you want to argue that functional programming is better than object-
oriented programming, you should take an object-oriented program, show how you
would rewrite it as a functional program, show us why the result is better,
and then show how the defects in the OO program are unavoidable within OO.

Some aspects of "goodness" for programs are:

* Brevity.

* Whether the program does something useful or at least entertaining.

* Local modifiability: that some modification of the program requires only local knowledge and local changes, rather than global knowledge and global changes. The more local, the better. This is conditional, though: requiring a ten-line change to a ten-line program is still better than requiring a twenty-line change to an eighty-line program. Demonstrating this requires that you show what is needed to make some particular change to both versions.

* Speed.

* Memory usage.

* Readability.

If you can show that your rewrite is better at least one of these axes and no
worse on any of them, and that the difference is a result of OO vs.
functional, then you will have shown that OO is worse than functional style
_for that program_. This shouldn't be hard; I think symbolic differentiation
is the usual example program for this. If it's better on some but worse on
others, then you've shown that _for that program_ , the choice is a
situationally-dependent tradeoff.

If you can show that this is true for a wide range of programs, then you will
have shown that OO is worse than functional in general.

However, you haven't shown it even for _one_ program. Instead you have some
vague bullshit example from some terrible textbook, some vague bullshit
example from a sci-fi movie, some theoretical objections stated in the form of
a series of mutually contradictory statements, a statement that you aren't
actually an idiot (in case we might think that from reading the rest of your
article, I guess?), a bunch of apparently false statements about Standard ML,
and a bunch of evidence that you're pretty much missing the point on OOP.

Edit: Aristotle Pagaltzis wrote an excellent takedown of what Gian is missing
a few years ago: <http://plasmasturm.org/log/340/>

I still haven't seen the non-shitty OO tutorial he was wishing for.

~~~
gdp
I think you're reading wayyyy to far into this. I wasn't making a this-versus-
that argument. I was having a rant about X being totally unfit for the purpose
for which it is sold (in this case, X is 'OOP' and its purpose is 'modeling
systems in an intuitive, natural way that corresponds to the real world'). I
even included the word "rant" in the first few sentences just so that people
who don't like reading rants could close the window at that point.

So basically, I respect that you disagree, but complaining that something that
was _clearly labeled_ as a rant didn't present objective evidence is asking a
little too much.

~~~
kragen
The context in which modeling systems in a way that corresponds to the real
world makes sense is when you're writing a simulation of the real world. The
Sims, say, or Knuth's elevator example. Historically this is where OO came
from. It was only later (with Smalltalk, for which the term "OO" was invented)
that it was used for more general programming.

My complaint wasn't that it was a rant. It was that it was a vacuous, boring
rant.

------
hassy
My take on this is:

1\. The OO model of C++ and Java (the languages the author has experience
with) is not the only model of OO around.

2\. State has to be maintained somewhere in the program. While functional
languages encourage minimizing state, nothing prevents the programmer from
doing the same in an OO language.

3\. Modeling is hard, regardless of the PL.

------
DanielStraight
The author has some good points, but none of the things he complains about are
a required part of OOP.

------
dreish
I agree with the general conclusion (as I understand it) that mutable objects
aren't a good way of modeling state, but the case has been made much more
strongly and more clearly elsewhere, such as here:

<http://clojure.blip.tv/file/812787/>

You can do state and concurrency correctly in an OO language with locks, but
it isn't practical. It gets exponentially more difficult as a project grows,
and realistically any human being is going to end up with something that only
almost always works correctly, with the occasional failures that are left over
almost impossible to find.

------
asciilifeform
Anyone else see this click-through warning?

 _Possible Blogger Terms of Service Violations_

 _This blog is currently under review due to possible Blogger Terms of Service
violations._

 _If you're a regular reader of this blog and are confident that the content
is appropriate, feel free to click "Proceed" to proceed to the blog. We
apologize for the inconvenience._

 _If you're an author of this blog, please follow the instructions on your
dashboard for removing this warning page._

~~~
gdp
Apparently blogger's automatic spam-detection system didn't like the flood of
traffic that suddenly hit the blog as a result of this article making the
front page. I've requested it be fixed, so hopefully that message won't stay
there for long.

------
fsniper
OOP is not something to do with real world objects. It's just told as this
way. OOP is about encapsulating "data objects", related data and programs in
close contact. Extending this brings us todays OOP concepts. But it is just
data bind togeter.

Giving real world objects as examples hides details. So thinking as physical
objects is a bad behavior in this context.

------
algorias
The author objects to a bicycle internally recording state that actually
belongs to "the world". The problem with this criticism is that a bicycle is
not a good example of something you'd model in a program. The abstraction was
taken too literally.

------
justin_vanw
I agree with the first comment, this is pure sketchy nonsense.

The bike example: If you only consider the bike to be some thing in the world,
and only give it attributes based on the world-context, then yes, when you
take the attributes predicated on that context out you are left with nothing.

But what about all the stuff you can say about a bike that isn't dependent on
the world-context? Color, weight, tire pressure, the wear state of the breaks,
how hard the brakes are being applied, the pressure being applied to the
pedals, the rate of rotation of the gears and movement of the chain, what gear
it is currently in, the state of the gear changing apparatus, the condition of
the spokes, the wear level of the tires, whether it has dirt or mud splattered
on it, what kind of seat it has, is it a girls or boys bike, a ten-speed or a
bmx, if there is a current 'rider' of the bike, and if so a reference to the
'rider' instance.

Now, you can use these attributes in methods that allow you to interact with
other objects in the environment. Suppose there is a 'rider' on the bike. The
'rider' can call methods like 'shift up' or 'push on pedal', and these methods
might take arguments. 'shift up' probably doesn't take arguments, 'push on
pedal' probably does, perhaps something like the pounds of force applied ot
the pedal in the forward direction.

Now, the 'world' object still has to exist. Collision detection, orientation
of objects in it, as well as speed must be tracked here. The world object
would also have to notify objects of 'what they hear' or of other sensory data
which must be applied to them. Finally, when 'press on pedal(5 pounds, 2
seconds)" is called, the bike must calculate - based on the current gear
ratio, the 'in-ness' of the gear system (perhaps the chain is off etc), how
oiled the chain and gears are - how much force is applied to the wheels, and
the world would have to notify the bike in response how much resistance there
is to that force, and somebody has to figure out what the final state is (for
example, if you are off the ground, the wheel would spin freely. Only the
world knows if you are on the ground, but only the bike knows how this effects
the computation of wheels speed.)

In the end, nothing will be a very good approximation of the real world. In
the real world, there are no objects, just amalgamation of particles whipping
around or sticking together. What we perceive as objects are just big sticky
clusters of particles, and even those particles aren't really objects, it's
globs all the way down.

The important part is that you can make really cool stuff if you pick an
appropriate approximation to model.

