
Does OO really match the way we think (1997) [pdf] - tjalfi
http://www.leshatton.org/Documents/OO_IS698.pdf
======
jwdunne
I think the big problem with OOP is that it's designed to simulate the real
world but has the real world backwards.

Real world objects are a composition of parts. The taxonomy of those objects,
and its constituent parts, is am artificial construct independent of how those
objects are composed. A frog is a frog because it fits some definition that
experts agree on. The taxonomy comes afterwards - the composition just is.

What we have is a model where the taxonomy comes first. We say a frog inherits
from an amphibian. What makes an amphibian an amphibian doesn't matter in OOP.
Further, the language rarely provides the same means for composition as it
does for inheritance and taxonomy. That's a problem.

In fact, the only reason why a frog is an amphibian is because it has parts
all amphibians share. The label comes afterwards, after looking at the
constituent parts.

In this way, OOP would benefit from composition-first, taxonomy after. An
object is a thing because of what it has (and this includes behaviour too),
not because of what it is or descended from.

It should be entirely possible for me to construct an object that fits the
definition of a frog without specifying I'm creating a frog.

~~~
dyarosla
I think you'd benefit from taking a look at Entity Component Systems.
Generally used for games, this programming pattern assigns behaviour to
entities based on the components that they have. Moreover, neither entities
nor components on their own actually own any behaviour. Behaviour occurs by
systems that operate on entities with the associated component "signature".

For example, an entity with a position and a velocity component (position
could hold x,y,z values and velocity vx,vy,vz values) could be operated on by
a movementSystem (which adds behaviour to any entities that have both a
position and velocity component, and updates position values based on velocity
values.)

The nice thing about such a system is that the taxonomy as you call it gets
defined when you instantiate the systems of your program. If you have entities
with position and velocity components but dont want to use a movementsystem to
operate on them, you simply dont instantiate the movementsystem. Pretty
flexible, but not used excessively outside of video games.

~~~
MikkoFinell
The problem with this approach is that systems will need info from multiple
components, so at some point you are forced to make the coupling that the ECS
was brought in to avoid. For example, the rendering system needs to know
entity position. So to which system does the "position component" belong? Not
all entities that have a position needs to be rendered, and neither do all
renderable entities require movement, and this same issue permeates all
aspects of the architecture.

~~~
bitwize
Components do not belong to a system. Any system can access any component.
Think of RDBMS stored procedures that operate on all rows matching certain
criteria; don't think OO style encapsulated "methods".

The system only operates on entities that have all the components they need.
So there won't be one rendering system but several: one for entities that
require movement, one for those which do not, etc.

~~~
dyarosla
Almost right. You wouldn't necessarily have a separate rendering system for
entities that require movement and those that do not.

Instead you would likely have an additional system that operates on entities
that have both position and render components and propagates updates from
position to render data. The render system for all entities with just a render
component would then remain the same.

This can be imagined as systems that work on signatures (a component set or
aspect that specifies whether an entity's components match the system's
criteria).

A render system would have an aspect of say [RenderComp] and a positionRender
system would have an aspect of say [RenderComp, PositionComp]. Note that the
positionRender system would not actually render anything, only serving as a
propagater of data.

------
alkonaut
OO solves some problems and creates others.

One must remember that the competing paradigm isn't functional programming but
imperative procedural programming. Very large code bases in C, Fortran, Cobol
aren't all that nice either.

It's unfortunate that ML and Lisp didn't gain greater traction but that's
likely due to Unix.

Many of OO's flaws are being addressed and are even missing from new
languages. Rust "feels" OO but isn't. If you write C#7 or Swift and avoid
inheritance and prefer immutable types as long as possible - how OO is your
code then?

The problem that OO solved is that it allows mediocre coders to iterate on
large scale code bases until a problem is solved. This is no small benefit in
industry. The drawback that the code is hard to maintain and prone to bugs is
an acceptable one.

Modern multi paradigm languages such as F# or Rust are really the way forward
I think. The Java/C++ way of OO was a good but expensive lesson.

~~~
sds2
> It's unfortunate that ML and Lisp didn't gain greater traction but that's
> likely due to Unix.

Lisp and ML are competing by nature(MLs are famous from their typesystems) and
their "failure" is not because of unix, but because of their inability to
deliver 'fast' & readable apps. Also, the learning curve...

~~~
macintux
Wait, learning curve? Relative to C++ or Java?

~~~
humanrebar
You can write something that passes acceptance tests in C++ without a lot of
effort. It's things like removing all the bugs, memory leaks, and undefined
behaviors that requires enormous expertise. There is certainly a _lot_ of
ground to cover before C++ mastery can be had, but simple OOP and procedural
programs aren't that bad.

~~~
bitwize
> You can write something that passes acceptance tests in C++ without a lot of
> effort.

True for freshman-year

    
    
        std::cout << "Hello, world!" << std::endl
    

programs maybe. People's heads asplode when they get into C++ with any
sophistication because they need to grasp several things at once: classes,
inheritance and polymorphism, pointers (smart or not), value vs. reference
types, etc. Java, JavaScript, and even Lisp go a long way toward hiding those
details from the programmer.

------
mjfisher
In reaction to some of the comments popping up re. OOP and functional
programming: I've come across quite a bit anti-OO sentiment in my career now,
and not nearly as much anti-functional sentiment. I suspect that the
prevalence of OOP has something to do with it - you're more likely to have
been exposed to bad OO code than any other type simply because there's more of
it. People often seem to draw an artificial distinction between OO and
functional styles - but they're both just techniques that can be applied to
solving problems and work well in combination. E.g. purely functional
immutable objects seem to yield very readable and maintainable code. You can
write bad code in any paradigm; but the more open you are to combining a
variety of techniques, the more options you have for creating a good solution
to the problem at hand.

~~~
squeeeeeeeeeee
> you're more likely to have been exposed to bad OO code than any other type
> simply because there's more of it

That's certainly true, but as someone who routinely has to go in and
bugfix/maintain classes contaning thousands of lines of code (sometimes in
themselves, more often collectively in their inheritance hierarchies), the
simple presence of extensively used member variables often is a massive
cognitive load. I'm not claiming that I'm some rockstar programmer who knows
better, but from my experience working with other programmers, member
variables might as well be called global variables.

tl;dr: Mutation, mutation everywhere.

------
skrebbel
Commenting more on this thread than the article: in my opinion, the idea that
OO and functional are somehow at odds with each other is misguided. There is
little about OO that doesn't mesh well with functional ideas, and vice versa.

The core concept of most OO designs is that data is coupled with the methods
that operate on that data. There is absolutely no reason why that can't work
with immutable data and pure functions. In fact, the String class in eg Java
and C# works just like that: each method returns a new instance.

Scala, for all its warts and complexities, has a fantastic feature called case
classes which _encourage_ combining the best of OO with the best of
functional. A case classes is both a class in the classical OO sense and an
ADT. Most case classes are immutable.

This is easy enough to simulate in many other languages, even if they don't
have case classes. For example, did you know Immutable.JS allows you to add
methods to Record prototypes?

~~~
tome
> The core concept of most OO designs is that data is coupled with the methods
> that operate on that data.

I've read this a lot, in this discussion and elsewhere, for years. But what
does it mean? Does it mean data is _syntactically_ coupled with state?
Otherwise I don't get why pretty much any C program is an OO design by this
definition.

~~~
skrebbel
Many C programs _are_ OO by this particular definition :) I take the least
ambitious definition of OO on purpose, because that definition is often the
one that matters the most. I mean message passing yada yada, if you look at
most OO software out in the wild, the key feature is the syntactical coupling
between nouns and the verbs that operate on those nouns.

Extra bonus though, compared to eg C, is that in OO languages you don't need
to spell out the type (plus polymorphism ofc). So String_trim(&myString)
becomes myString->trim() and that's shorter and, most of the time, equally
clear and less noisy.

I miss this most when coding Elixir.

------
cousin_it
No comment about OO in general, but I think Java/C# is a damn fine language
design, avoiding many problems of newer paradigms. Here's an example:

1) Java: starts out with one opaque string type, because that's what OO
methodology says. Changes the internals when needed. All clients continue to
work forever.

2) Haskell: starts out with strings as exposed linked lists of characters,
because functional methodology says exposed algebraic types are OK. Sticks
with this mistake for many years, then recognizes that opaque would be better
and introduces a new type Text. Can't change the old one or make them
compatible. Moreover the new type exists in strict and lazy variants, because
Haskell methodology says people want that.

3) Rust: starts out with two string types, because the language design
suggests both should exist (String and &str).

It's not just about strings. The same happens with compilation speed, binary
compatibility, etc. "Modern" languages get it wrong and can't fix it, Java 1.0
gets it right and it stays right.

~~~
thegeomaster
The String and &str thing is a common criticism of Rust, but I feel it's a bit
shallow when said without context. Maybe it's just me, but it makes sense when
you consider Rust's ownership semantics (which are a new idea in language
design, so you can't really look at how other languages solved issues arising
from them).

Basically, when you have the notion of ownership/lifetime in a language, you
have to make a distinction between an _owned_ and a _borrowed_ thing. When you
pass an owned thing to a function, you give up your ownership of it, and can't
use it anymore. When you pass a borrowed thing, you keep the ownership, and
the compiler tries to prove that, based on ownership info it has, it lives
long enough for the operation to be safe. Just as String and &str are owned-
borrowed counterparts, you also have e.g. Vector<u8> and &[u8] (the former is
an owned vector, the latter is a read-only, borrowed view into that vector)
and many more examples of this dichotomy.

I don't see how this could have been solved in Rust without having those two
types.

------
BoiledCabbage
OOP did more to set back program design than anything else I can think of. It
was incredibly wrong, has sent so many smart minds down a poor path. If for
example functional has taken prominence in the 90s we'd be in a much better
place now.

~~~
MarkMc
I have the polar opposite view. I love OOP because it provides a way to
elegantly solve so many problems.

To take a concrete example, consider the undo-redo mechanism in a text editor.
It seems natural to create a list of objects with each object representing the
action that can be undone or redone, and a pointer to the most recent action
object. Undoing executes the 'undo' method and moves the pointer to the
previous action. Redoing moves the pointer to the next action and calls it's
'redo' method.

You would have a 'delete text' type of action which knows how to remove a
particular chunk of text and put it back. You would have a 'change text
colour' action which knows how to change text to a particular colour and
revert back. You might have an 'insert jpeg' action which knows how to add a
picture and remove it from the document.

Crucially, each action object in the list should encapsulate it's data and
behaviour. It makes the undo-redo framework so much simpler if the framework
knows nothing about each type of action, besides the fact that each action
object has some kind of undo and redo behaviour.

I cannot see how you could get a simpler design without OO principles such as
coupling the data and methods of each type of action, or without hiding the
implementation details of each action from the undo-redo framework.

~~~
Tehnix
Heh, check out time-travel debugging and be amazed at how simple a _much_ more
powerful “undo” can be made when purity is involved (in FP langs, e.g. Elm or
Haskell).

Seriously though, design wise there was not much you said that was specific to
OO. Take for example:

\- all actions are a data type

\- the history is a list of actions (in LIFO style for the purpose of
simplicity here)

\- undo pops the list and puts undo in another list

\- redo replays the undo list onto the history list

A bit more outlined, but nothing OO there, it was in fact entirely functional.

~~~
pjmlp
Already present in Smalltalk, Lisp and Mesa/Cedar development environments at
Xerox PARC, no need for FP advocating for it.

~~~
Tehnix
I guess immutability is the actual thing that makes it easy, and arguably Lisp
is also an FP lang. m Main point though was the ease of doing it in a pure
language, almost trivial.

------
sgt101
I love work like this - a real attempt to understand what was happening.
Genuine scholarship.

But it illustrates the issues with this sort of work. This is really about C++
vs C/Pascal and not OO vs Proc. Also this is 1997 C++ which I earned a living
from for a brief moment, and I can attest, it was horrible, and very different
from 2017 C++.

From my perspective today : we need to separate parametric and polymorphic oo
in our thinking and the big problem is that programmers use these tools to the
limit (creating objects with 3+ parameters or deep inheritance hierarchies)
and weave silly complexity into the code base .

In a commercial setting the biggest impact I have seen is a project that
became impossible to staff because as soon as the developers saw the code base
they started looking for other work. It was really good code developed by a
two brilliant people initially and then three or four more smart ones as the
project grew, but when the lead left it was just too complex - due to prolific
use of generics and a obsession with ORM.

~~~
mannykannot
> This is really about C++ vs C/Pascal and not OO vs Proc. Also this is 1997
> C++...

I can imagine the Smalltalk community rolling its collective eyes and saying
"that's not OO..."

My issue with the primary study is that the two programs are not really
comparable: a think a C++ parser was a harder problem than a C parser (even
given that it is 1997's C++), and this is backed up in the study:

"The C++ parser by further contrast is a recursive descent parser owing to the
intractability of parsing C++ using 1 token-lookahead grammars. In other
words, they are very different products..."

In mitigation, it says that the C++ parser, as used in the comparison, did not
parse the full language, thereby presumably reducing the difference in the
complexity of the requirements, but I think the difference in architecture
alone is enough to raise doubts over the significance of the results.

------
kccqzy
C++'s implementation of OO isn't that good to begin with, mainly due to
compatibility concerns. Perhaps we should look for a better OO language for
comparison, say Smalltalk.

~~~
robertkrahn01
Indeed! And not every language that claims to be OO actually follows the basic
ideas [1,2]. So, Smalltalk, as e.g Squeak [3] or Pharo [4] is a good place to
start looking and learning but also Erlang [5] and Clojure [6]. State is
necessary not "evil" but needs to be managed well. And most OO-languages have,
apart from the assignment operation, no abstractions for.

[1]
[http://wiki.c2.com/?AlanKayOnMessaging](http://wiki.c2.com/?AlanKayOnMessaging)
[2]
[http://worrydream.com/EarlyHistoryOfSmalltalk/](http://worrydream.com/EarlyHistoryOfSmalltalk/)
[3] [http://squeak.org/](http://squeak.org/) [4]
[https://pharo.org/](https://pharo.org/) [5]
[http://www.infoq.com/interviews/johnson-armstrong-
oop](http://www.infoq.com/interviews/johnson-armstrong-oop) [6]
[http://thinkrelevance.com/blog/2013/11/07/when-should-you-
us...](http://thinkrelevance.com/blog/2013/11/07/when-should-you-use-clojures-
object-oriented-features)

~~~
willtim
OOP does not offer true state encapsulation, it just hides it. Objects are
always potentially stateful when reasoned about externally. This means that
all objects in your system could potentially contribute to the global state
space, resulting in a combinatorial explosion of state. This makes programs
difficult to reason about and is not a good general approach.

In contrast, functional programming makes state explicit. This makes it easier
to manage and control state.

~~~
TimMurnaghan
It's cute how people thing that functional will fix everything.

In what way does functional make state explicit? If I look at a structure (if
you have one in your language) and ask who changes this part of it across a
large code base - it's much worse when you've just got a bunch of functions
(with bad names) which can be hiding anywhere.

And the "reasoned about" shibboleth. What "reasoning" do you actually do.

Don't get me wrong - I have a long history in Lisp and ML and they're good
languages in which good people can write good software. But no magic bullets.

In another part of the development world I've seen React programmers jumping
on the functional bandwagon and deciding that all components have to be
stateless. Taking the state outside the components means that we have lots of
bugs with mistaken state sharing. So external state doesn't equal well-
managed.

~~~
quickthrower2
In functional programming n Haskell functions are pure so there is no state
just an input and an output.

The exception is the IO entry point.

There is a lot of opportunity to sandbox things so that if you know the type
of the function you know what it can or can't do to the programs state.

------
theboywho
I've noticed most HN comments transformed from being discussions about the
_content_ of the article to comments discussing the _topic_ of the article
being posted, not sure if this is healthy, but the risk is HN becoming an echo
chamber where people discuss opinions, and the posts becoming just topic
triggers. We'll see how it evolves.

~~~
SwellJoe
Actually reading the whole article takes time, while reading the title and
posting a knee-jerk reaction takes only a moment. One of the curses of a
hotness-oriented system like HN is that earlier comments receive the bulk of
the upvotes and responses, so it becomes less interesting to comment as time
goes on.

There are lots of little rules in place to minimize the damage of this (like
no memes, jokes, pics, etc.; HN actively discourages clickbait), but it can't
force people to actually read the articles before responding. And, one doesn't
have to read the articles to vote, either (again, HN mitigates that problem
somewhat by requiring a minimum level of upvotes before being able to vote,
etc.).

It's hard to have a substantive conversation online when so many of the
incentives are for responding quickly (and probably without going too far
against popular opinion within whatever community you're in).

~~~
krapp
> but it can't force people to actually read the articles before responding

They could hash the title for a minimum time, or until at least three comments
are posted.

That would at least force people to click the link to find out what's there,
and filter out commenters too lazy to do even that.

~~~
throwaway413
Or just force the user to click the link before the comment box is enabled for
that posting.

~~~
mgkimsal
then waiting X minutes before enabling the comment box too, to avoid just
clicking and posting?

------
barking
I found this anti-oop video very persuasive.
[https://youtu.be/QM1iUe6IofM](https://youtu.be/QM1iUe6IofM)

He also had a couple of follow up ones.

Basically he blames java for oop's popularity. He maintains that oop's
combining of methods and data is actually a fault and not a benefit. That
every good oop promises apart from inheritance (which is bad anyway) is more
easily achieved in procedural programming. OOP promotes endless meaningless
abstractions because the problems programmers deal with are not amenable to
neat abstractions. So while oop looks great when dealing with animals, cats
and dogs, in real programming you end up with an explosion of difficult to
name classes, the so-called 'kingdom of nouns'.

~~~
tome
I'm sad you've been downvoted. I loved this video.

~~~
barking
Thanks! I've always found it unnatural to design solutions in an oop way. And
any time I have done it the code always seems a lot harder to debug
afterwards. At the same time I kinda always felt that my preference for
procedural code reflected badly on my programming skills. To hear someone who
is clearly skilled and knowledgeable argue so well in support of the way i
like to program was a bit like having a weight lifted off my shoulders.

------
mojuba
Should be said in defence of C++, whether its own OO model is good enough for
you or not, but object scoping and destructors _alone_ had brought a
significant paradigm shift in programming in the 1990s. Although these
concepts never really made it to other mainstream languages in such a direct
form, but they certainly inspired all kinds of memory management models (ARC,
GC). The result is that C++ style destructors and scope management exist
implicitly in pretty much every language today.

As for the OO itself, I think the problem is that any poorly written non-OO
code typically goes unnoticed or just labelled "bad code", whereas poorly
written OO code is labelled as such: poorly written OO code. They both are
equally bad. We need to accept that if something is wrapped into a class or
even some hierarchy, it is by itself not a guarantee at all that it can be
useful or functional.

------
jcelerier
All these guys bashing OO and in the meantime every software stack that ended
up in their comment leaving their home connection is object-oriented (even if
not necessarily written in an OO-friendly language): web browser, linux,
windows or mac kernel, router firmware... Seriously guys, if you think OO has
failed you are oblivious to the amount of successful OO software that everyone
uses every day.

~~~
wfunction
> Seriously guys, if you think OO has failed you are _obnoxious_ to the amount
> of successful OO software that everyone uses every day.

Not sure what you mean. Do you mean _oblivious_?

~~~
alkonaut
Amphibious pitcher debuts in MLB.

~~~
wfunction
What?

~~~
alkonaut
Sorry, that was a viral image this week :)

[https://twitter.com/johnmclarkejr/status/74106144399966617](https://twitter.com/johnmclarkejr/status/74106144399966617)

------
buzzybee
My strategy for personal coding recently has shifted towards a sincere
exploitation of automatic programming(in a manner similar to model-driven
development or language-oriented programming, or the research of VPRI). The
overall feedback loop looks like this:

* Write an initial mockup that exercises APIs and data paths in an imperative, mostly-straightline coding style

* Write a source code generator that reproduces part of the mockup by starting with the original code as a string and gradually reworking it into a smaller specification.

* Now maintain and extend the code generator, and write new mockup elements to develop features.

The mockup doesn't have to be 100% correct or clean, nor does the code
generator have to be 100% clean itself, nor does 100% of the code have to be
automated(as long as clear separation between hand-written modules and
automatic ones exists), but the mockup is necessary as a skeleton to guide the
initial development, and similar, comprehensible output one layer down is a
design goal. Language-level macro systems are not typically sufficient for
this task since they tend to obscure their resulting output, and thus become
harder to debug. Languages that can deal well with strings and sum types, on
the other hand, are golden as generator sources since they'll add another
layer of checks.

I'm still only using this for personal code, but it's gradually becoming more
"real" in my head as I pursue it: the thing that stopped me before was
developing the right feedback loop, and I'm convinced that the way to go is
with a pretty lean base implementation(Go is an example of how much language
power I'd want to be using in the target output) and an assumption that you're
building a bespoke generator for the application, that won't be used anywhere
else.

Source code generation gets a bad rap because the immediate payoffs are rare,
and it's easy to take an undisciplined approach that just emits unreadable
boilerplate without gaining anything, but the potential benefits are huge and
make me not really care about design patterns or frameworks or traditional
"paradigms" anymore. Those don't achieve anywhere near the same amount of
empowerment.

~~~
stevedh
This is an approach I've been exploring myself. Do you have any suggestions or
recommendations as to languages that lend them selves well to this approach?

------
eksemplar
> Studying the copious literature of OO, the central features which define an
> OO system seem a little ill-defined.

I didn't know opinion pieces could be disguised as academia. Of course the
article has some interesting points about human memory, but that's why we have
things like single responsibilities.

~~~
exDM69
But it is not an opinion. There is no universally accepted definition of OO
let alone a formal, axiomatic definition, and that makes it ill-defined.

If you disagree, point to a definition of OO that you think is "correct".

~~~
Ace17
I suggest to look at Alan Kay's definition, since he's the one who invented
the term "object oriented".

[http://www.purl.org/stefan_ram/pub/doc_kay_oop_en](http://www.purl.org/stefan_ram/pub/doc_kay_oop_en)

~~~
exDM69
Well, Alan Kay's definition is just one definition and as evidenced by the
rest of this thread, it's far from being universally accepted and definitely
not the definition used in the mainstream "OO" languages.

Further, that email thread is far from being a formal definition. In that
email there's a pointer to a ISO standard doc, but that's hardly authoritative
either.

It seems like every language (and every programmer) has their own idea of OO,
which is why I consider it quite apt to call it "ill-defined". That's not to
say that OO programming itself is bad, more that the term "OO" is bad.

------
SeanDav
OO is just a tool, a powerful one at that. Like any tool, it can be abused,
overused and incorrectly used - the classic comment that comes to mind is:

"When the tool you have in your hand is a hammer, every problem looks like a
nail..."

------
twh
The paper specifically calls out inheritance and polymorphism as problematic,
especially in the context of maintaining existing code. Which makes me think
that code visibility is at least part of the issue. We've always had
functions, libraries, and "includes", but their re-use was infamously course
grained, static, or not well leveraged outside their initial scope.

Things like inheritance, polymorphism, dependency injection, and "abstracting
things away" in general have made it practical and common for implementation
details to evaporate in such a way that we don't (and maybe _can 't_) keep
them in our heads when we are maintaining existing code.

This is great if all those class hierarchies and abstracted implementations
are bug-free and work the way you anticipate them working (i.e. if they fit
your mental model). As soon as they don't, or they get too complex and too
deep, you're in for a world of hurt and confusion.

------
avodonosov
How to model a door.

    
    
        class Door {
          void open() {...}
          void close() {...}
        }
    
        door.open().
    

But can a door open itself? Maybe

    
    
        Man petya = ...
        petya.open(door);
    

But can a door be opened if it's not installed? So walls should also come into
play when we think about door and its methods.

It's difficult to model the world with OOP (at least in its current state).

~~~
brabel
A `Door` is not an agent, so no, it can't open itself (unless it's a game and
your doors have agency).

When you say a door can be opened, you are making the assumption that the door
is installed in some sort of building. But then, the door is a component of
that building, not just a stand-alone door. It can only be opened in that
context.

So I would suggest something like this:

    
    
        class Door(Material, Size)
        class Room(List<RoomConnection>, Size)
        enum DoorState { Closed, Open, Locked }
        class RoomConnection(Room, Room, Optional<(Door, DoorState)>, Size)
    

To open the door, you don't need a method in any of these "data" classes, you
just need to update the door state given there's a door in a room connection
you're interested in.

The room connection may or may not have a door, and that could change over
time. If it does have a door, then the door must have a state (but not all
doors have a state, only the ones that are in a Room Connection, possibly
others).

Notice that to update the room connection, you don't need mutable state
locally... you just need a way to provide a new RoomConnection to code where
opening a door may be possible (normally, you're given a RoomConnection as an
input, and you might give a new one, basic FP style but OOP can also operate
in that way).

So, I don't think it's that hard if you know what you're doing.

I don't want to even comment on the suggestion to have a `Man.open(Door)`
method :) that's really not good.

~~~
avodonosov
You still follow the naive OOP thinking and it remains ridiculous.

For example, why Room?

------
yen223
A common sentiment expressed in threads like this is that people can write bad
code in any language, therefore language doesn't matter. While that may be
true, I don't think judging a language by the worse parts is a useful
exercise. I'd rather judge a language by its best parts.

To that end, can someone point to me an example of object-oriented code that
they feel is elegant?

~~~
krylon
At work, I am currently working a program that needs to read XML messages from
a message queue, and depending on the type of message extract several pieces
of data from it and write them to a specific list in a SharePoint server.

I wrote an abstract base class that contains all of the boiler plate code for
dealing with SharePoint, and then one subclass for each type of message I need
to deal with; those subclasses only need to override a few methods to deal
with the fields from the XML message and with the specific SharePoint list
they need to write to.

It is not great (the task is just too dull for that), but I am happy with the
approach I have chosen because I can add support for new message types fairly
easily.

That being said, I do not think OOP is the answer to all (programming)
questions, nor is it the worst idea ever. Some programs can be expressed in
terms of objects and inheritance very easily, just as some can be expressed in
functional terms very easily.

------
chobytes
I think this latest resurgence of OOP skepticism could be a good thing, but I
can see it easily turn into folks just using OOP as a scapegoat for bad
design.

I worry as well about the push for FP to somehow 'replace' OO, when really
they address different concerns, and can actually complement eachother.

~~~
jjrrmm
You're absolutely right, just look at #select:, #collect: and #reduce: in
Smalltalk for example! It's totally amazing.

------
abhishekash
But then if OO is a dud then why do we have some of its implementations C#,
C++ and Java drive most of the enterprise. If they would not have existed
would we have same amount to faith of enterprises to move to adopt software
applications to run daily business.

~~~
rleigh
OO was a fad for how many years? All these languages were strongly influenced
by this, and this greatly colours the worldview programmers have who work with
these languages.

If you work in Java, everything is contained within a class. You can't easily
think outside the OO box because the language insists that everything you do
is done in terms of OO, and this has great implications from the standard
library, to primitive type boxing. It's very much constrained by the prevalent
trends of the mid-90s. C++ is a more OO agnostic, it being something you can
opt into as and when it makes sense.

I certainly don't think OO is a "dud", and it's provided a conceptual
framework for programmers of wildly varying abilities to create and maintain
vastly complicated codebases. But... it's only one way of many to structure
and reason about program logic and data, and to constrain oneself to only
using OO is greatly limiting. Now the hype has died down, I hope we can use OO
where it fits, and avoid it where it does not, rather than as a blunt
instrument for every problem?

The main problem I see in my day to day work (imaging related) is that OO is
too costly. Arrays of object instances are too cache unfriendly. And code
doesn't always need to be directly tied to data. I see Java code using
collections of primitive arrays in place of objects because most OO languages
don't provide a means of laying out objects in column stores, even though it
wouldn't be technically difficult (just different offsets to members rather
than packed structures). Treating objects as individual private collections of
state leads to only being able to work with an object-centric rather than
data-centric view, which can be quite detrimental. It's this view that leads
to abominations like database object mappers, treating tabular data as object
collections when they are not. While such things are possible and even
popular, they often come with significant tradeoffs. I've encountered
developers who are completely constrained within an OO worldview and can't
take the blinkers off and see what's possible outside the box.

------
frik
Prototype based inheritance (e.g. JavaScript, Lua) is a much better concept.
(It's much more powerful and allows you even to implement class based
inheritance.)

Also functional programming has its benefits.

The 1990s/2000s with the OO hype around C++/Java/C# was a set back.

------
Pica_soO
Think of the program, not as a program, but as a family. A Family has multiple
persons(threads), who can do diffrent jobs(functions). A family has a home
(system) ...

------
tanilama
2017 still debating about OO sounds like a bad idea.

------
agumonkey
Does the way we naturally think is the way to solve problems ? no. OO isn't
useful.

------
joshbaptiste
famed Youtube programmer Brian Will also dislikes OO
[https://www.youtube.com/watch?v=QM1iUe6IofM&t=2096s](https://www.youtube.com/watch?v=QM1iUe6IofM&t=2096s)

