2010/08/26

Ten Things I Hate About Object-Oriented Programming

Filed under: Editorial — Tags: — Oscar Nierstrasz @ 17:25

Boy, I some days I really hate object-oriented programming.

Apparently I’m not the only one. In the immortal words of Edsger Dijkstra: “Object-oriented programming is an exceptionally bad idea which could only have originated in California.”

Well, I’m not normally one to complain, but I think it is time to step back and take a serious look at what is wrong with OOP. In this spirit, I have prepared a modest list of Ten Things I Hate About Object-Oriented Programming.

1. Paradigm

What is the object-oriented paradigm anyway? Can we get a straight story on this? I have heard so many different versions of this that I really don’t know myself what it is.

If we go back to the origins of Smalltalk, we encounter the mantra, “Everything is an object”. Except variables. And packages. And primitives. And numbers and classes are also not really objects, and so on. Clearly “Everything is an object” cannot be the essence of the paradigm.

What is fundamental to OOP? Peter Wegner once proposed that objects + classes + inheritance were essential to object-oriented languages [http://doi.acm.org/10.1145/38807.38823]. Every programming language, however, supports these features differently, and they may not even support them as built-in features at all, so that is also clearly not the paradigm of OOP.

Others argue convincingly that OOP is really about Encapsulation, Data Abstraction and Information Hiding. The problem is that some sources will tell you that these are just different words for the same concepts. Yet other sources tell us that the three are fundamentally different in subtle ways.

Since the mid-eighties, several myths have been propagated about OOP. One of these is the Myth of Reuse, which says that OOP makes you more productive because instead of developing your code from scratch, you can just inherit from existing code and extend it. The other is the Myth of Design, which implies that analysis, design and implementation follow seamlessly from one another because it’s objects all the way down. Obviously neither of these candidates could really be the OO paradigm.

Let’s look at other paradigms which offer a particular way to solve programming problems. Procedural programming is often described as programs = data + algorithms. Logic programming says programs = facts + rules. Functional programming might be programs = functions + functions. This suggest that OOP means programs = objects + messages. Nice try, but this misses the point, I think.

For me the point of OOP is that it isn’t a paradigm like procedural, logic or functional programming. Instead, OOP says “for every problem you should design your own paradigm”. In other words, the OO paradigm really is: Programming is Modeling

2. Object-Oriented Programming Languages

Another thing I hate is the way that everybody loves to hate the other guy’s programming language. We like to divide the world into curly brackets vs square brackets vs round brackets.

Here are some of the nice things that people have said about some of our favorite OOPLs:

“C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, it blows away your whole leg.”

It was Bjarne Stroustrup who said that, so that’s ok, I guess.

“Actually I made up the term ‘object-oriented’, and I can tell you I did not have C++ in mind.” — Alan Kay

“There are only two things wrong with C++: The initial concept and the implementation.” — Bertrand Meyer

“Within C++, there is a much smaller and cleaner language struggling to get out.” — Bjarne Stroustrup

“C++ is history repeated as tragedy. Java is history repeated as farce.” — Scott McKay

“Java, the best argument for Smalltalk since C++.” — Frank Winkler

“If Java had true garbage collection, most programs would delete themselves upon execution.” — Robert Sewell

But perhaps the best blanket condemnation is the following:

“There are only two kinds of languages: the ones people complain about and the ones nobody uses.” — Bjarne Stroustrup

3. Classes

Classes drive me crazy. That might seem strange, so let me explain why.

Clearly classes should be great. Our brain excels at classifying everything around us. So it seems natural to classify everything in OO programs too.

However, in the real world, there are only objects. Classes exist only in our minds. Can you give me a single real-world example of class that is a true, physical entity? No, I didn’t think so.

Now, here’s the problem. Have you ever considered why it is so much harder to understand OO programs than procedural ones?

Well, in procedural programs procedures call other procedures. Procedural source code shows us … procedures calling other procedures. That’s nice and easy, isn’t it?

In OO programs, objects send messages to other objects. OO source code shows us … classes inheriting from classes. Oops. There is a complete disconnect in OOP between the source code and the runtime entities. Our tools don’t help us because our IDEs show us classes, not objects.

I think that’s probably why Smalltalkers like to program in the debugger. The debugger lets us get our hands on the running objects and program them directly.

Here is my message for tool designers: please give us an IDE that shows us objects instead of classes!

4. Methods

To be fair, I hate methods too.

As we have all learned, methods in good OO programs should be short and sweet. Lots of little methods are good for development, understanding, reuse, and so on. Well, what’s the problem with that?

Well, consider that we actually spend more time reading OO code than writing it. This is what is known as productivity. Instead of spending many hours writing a lot of code to add some new functionality, we only have to write a few lines of code to get the new functionality in there, but we spend many hours trying to figure out which few lines of code to write!

One of the reasons it takes us so long is that we spend much of our time bouncing back and forth between … lots of little methods.

This is sometimes known as the Lost in Space syndrome. It has been reported since the early days of OOP. To quote Adele Goldberg, “In Smalltalk, everything happens somewhere else.”

I believe that the code-oriented view of today’s IDEs is largely to blame — given that OO code does not accurately reflect the running application, the IDE gets in our way instead of helping us to bridge the gap. Another reason I believe that Smalltalkers like to develop in the debugger is that it lets them clearly see which objects are communicating with which other objects. I am guessing that one of the reasons that Test-Driven Development is popular is that it also exposes object interactions during development.

It is not OOP that is broken — we just haven’t figured out (after over 40 years) how best to develop with it. We need to ask ourselves: Why should the source code be the dominant view in the IDE?

I want an IDE that lets me jump from the running application to the code and back again. (For a demonstration of this idea, have a look at the Seaside web development platform which allows you to navigate directly from a running web application to the editable source code. [http://seaside.st])

5. Types

OK, I admit it. I am an impatient guy, and I hate having to say everything twice. Types force me to do that.

I’m sure some of you are thinking — “Oh, how could you program in an untyped language. You could never be sure your code is correct.”

Of course there is no such thing as an “untyped” programming language — there are just statically and dynamically typed ones. Static types just prevent you from writing certain kinds of code. There is nothing wrong with that, in principle.

There are several problems, however, with types as we know them. First of all they tend to lead to a false sense of security. Just because your Java program compiles does not mean it has no errors (even type errors).

Second of all, and much more evil, is that type systems assume the world is consistent, but it isn’t! This makes it harder to write certain useful kinds of programs (especially reflective ones). Type systems cannot deal well with the fact that programs change, and that different bits of complex systems may not be consistent.

Finally, type systems don’t cope well with the fact that there are different useful notions of types. There is no one type system to rule them all. Recall the pain we experienced to extend Java with generics. These days there are many interesting and useful type systems being developed, but we cannot extend Java to accommodate them all. Gilad Bracha has proposed that type systems should not only be optional, in the sense that we should be able to run programs even if the type system is unhappy, but that they should be pluggable, meaning that we can plug multiple type systems into different parts of our programs. [http://bracha.org/pluggableTypesPosition.pdf] We need to take this proposal seriously and explore how our languages and development tools can be more easily adapted to diverse type systems.

6. Change

“Change is inevitable — except from a vending machine.” — Robert C. Gallagher

We all hate change, right? So, if everyone hates change, why do we all complain when things don’t get better? We know that useful programs must change, or they degrade over time.

(Incidentally, you know the difference between hardware and software? Hardware degrades if you don’t maintain it.)

Given that real programs must change, you would think that languages and their IDEs would support this. I challenge you, however, to name a single programming language mechanism that supports change. Those mechanisms that do deal with change restrict and control it rather than enable it.

The world is not consistent, but we can cope with that just fine. Context is a great tool for managing change and inconsistency. We are perfectly comfortable adapting our expectations and our behavior in our daily lives depending on the context in which we find ourselves, but the programs we write break immediately if their context changes.

I want to see context as a first-class concept in OO languages and IDEs. Both source code and running software should be able to adapt to changing context. I believe that many design patterns and idioms (such as visitors, and dependency injection) are simply artifacts of the lack of support for context, and would disappear if context were available as a first-class construct.

7. Design Patterns

Patterns. Can’t live with ’em, can’t live without ’em.

Every single design pattern makes your design more complicated.

Visitors. I rest my case.

8. Methodologies

“All methodologies are based on fear.” — Kent Beck

Evidently some of my students follow the Chuck Norris school of Agile Development:

“Chuck Norris pairs alone.”

“Chuck Norris doesn’t do iterative development. It’s right the first time, every time.”

“Chuck Norris doesn’t do documentation. He stares down the code until it tells him everything he wants to know.”

9. UML

Bertrand Meyer tells this story about always wondering why diagrammatic modeling languages were always so popular, until one day it hit him: “Bubbles don’t crash.” I believe his point is that OO languages are modeling languages. (AKA “All you need is code”)

There similarly appears to be something fundamentally wrong with model-driven development as it is usually understood — instead of generating code from models, the model should be the code.

By analogy, when FORTRAN was invented, it was sold as a high-level language from which source code would be generated. Nowadays we think of the high-level languages as being the source code.

I like to think that one day, when we grow up, perhaps we will think of the model as being the source code.

10. The Next New Thing

Finally, I hate the catchphrase: “Objects are not enough. We need …” Over the years we have needed frameworks, components, aspects, services (which, curiously, seems to bring us back to procedural programming!).

Given the fact that objects clearly never were enough, isn’t it odd that they have served us so well over all these years?

Conclusion?

25 years ago we did not expect object-oriented programming to last as a “new” phenomenon for so long. We thought that OO conferences like ECOOP, OOPSLA and TOOLS would last for 4 or 5 years and then fade into the mainstream. It is too soon to dismiss OOP as just being part of the mainstream. Obviously we cannot feel passionately about something that does not interest us. The fact that academic and industrial research is still continuing suggests that there is something deep and important going on that we do not yet fully understand.

OOP is about taming complexity through modeling, but we have not mastered this yet, possibly because we have difficulty distinguishing real and accidental complexity.

I believe that to make further progress we must focus on change and how OOP can facilitate change. After all these years, we are still in the early days of OOP and understanding what it has to offer us.

Oscar Nierstrasz
[Banquet speech given at ECOOP 2010. Maribor, June 24, 2010]

48 Comments »

  1. 1, 2, 10 & Conclusion: Solid points (+1 for being informative)

    Rest is all useless bashing (I’m sorry for using this term but I couldn’t find a decent word for being pessimist for the sake of it, complaining without considering the same points for the other side of things, …)

    Comment by Monis Iqbal — 2010/08/26 @ 21:33

  2. I see OO’s paradigm as “giving actions to data”. All the rest is variable in OO languages, but the common ground is that data has behaviour.

    Whatever you do with that, the way you protect data or behaviour, it’s up to the language. But from Perl to SmallTalk, data has behaviour and the name of that union is “object”.

    While Perl “bless” objects with “module descriptions” and C++ have “classes” to give types to “objects”, both do the same thing to “objects”: it gives them behaviour.

    From that, comes the concept of empty objects with only behaviour (helper classes), empty objects with empty behaviour but with style (interfaces), objects without behaviour (PODs), grouping of objects (inheritance, traits, templates). Everything those languages do is with objects, but the way you describe the grouping is via classes or modules, or whatever you want it to be called.

    In the end, there’s only one thing that survives: objects and its behaviours. That’s what’s all about OO.

    What you complain (and I agree) is how languages implement Object-Oriented design. Stroustroup went wrong when he first designed “C with Classes”, it should have been “Objects in C” to give the right weight to the right things.

    But well, that’s how things went because it’s more difficult to do what you say (run view in IDEs) than statically define everything, though it might not be the most logical view for the programmer.

    Comment by Renato Golin — 2010/08/29 @ 16:08

  3. You asked for “a single programming language mechanism that supports change”. I’ll give you two!

    1. Polymorphism: depending on how it’s used polymorphism can be the most important mechanism in OOP for supporting change. Not arbitrary change, to be sure, but at least those abstractions conceived of by the original programmer.
    2. IDE Refactorings: (not strictly a language mechanism, but the question was posed in the context of PL and IDE support for change). Modern IDEs increasingly support refactorings, both simple and more complex. The support is not always perfect, but it certainly aids the programmer in making changes to the design of software.

    Comment by @smalltalkhacker — 2010/08/29 @ 22:04

  4. I agree with you but I love OO too :)

    Comment by Jose — 2010/08/31 @ 17:32

  5. Thank you for the thoughtful reflection on objects. I agree that more context is often valuable when programming with objects. I do it with Java/Eclipse as detailed here: http://www.threeriversinstitute.org/ProgrammingInTheConcrete.htm

    Comment by Kent Beck — 2010/08/31 @ 18:57

  6. Thanks for this wonderful post. I wished I had attended ecoop this year to hear it real

    Comment by Alexandre Bergel — 2010/09/01 @ 01:28

  7. If you hate classes in the object-oriented concept model, then you’ll REALLY hate a Category-Theoretic mathematical understanding of computer science and software development (whether O-O or not).

    This prejudice usually indicates the triumph of training over education – you have learned to conceptualize in one, dominating paradigm to the exclusion of all others. Certainly, the same can be said of those who exclusively conceptualize in O-O, or AO or SO or …

    Comment by Ken Lloyd — 2010/09/02 @ 14:02

  8. > However, in the real world, there are only objects. Classes exist only in our minds. Can you give me a single real-world example of class that is a true, physical entity?

    public interface Car {
    public void toggleEngine();
    public void turnSteeringWheel();
    public void applyThrottle();
    public void applyBrake();
    }

    public class DefaultCar implements Car { /*..* }

    public class HondaCivic extends DefaultCar { /*..*/ }

    public class ToyotaCamry extends DefaultCar { /*..*/ }

    and so on …

    It’s really a logical way to organize concepts.

    > In OO programs, objects send messages to other objects.

    /** car **/
    public void toggleEngine() {
    getStarter().startEngine();
    }

    /** starter **/
    public void startEngine() {
    List pistons = /*…*/
    getFuelInjector().injectFuel(pistons);
    /* and so on */
    }

    It’s really a logical way for concepts to interact.

    Comment by rhume55 — 2010/09/11 @ 19:49

  9. “If we go back to the origins of Smalltalk, we encounter the mantra, “Everything is an object”. Except variables. And packages. And primitives. And numbers and classes are also not really objects, and so on. Clearly “Everything is an object” cannot be the essence of the paradigm.”

    You are wrong. Variables are modeled as a either a Dictionary for global variables, eg: Smalltalk at: #VarName, or a positional mapping for local, instance, and other variables, eg: tempVarAt:/instVarAt:… as for packages, different systems model them in different ways, but always as objects, and numbers and classes are objects. Primitive methods are primitives, but still objects.

    Comment by kevin — 2010/09/11 @ 20:11

  10. Love the write up it shows that we are very often slaves to process and procedures.

    Comment by Bo — 2010/09/13 @ 04:39

  11. An object is a thing. Saying “everything is an object” is as meaningless as saying “everything is a thing.”

    What object oriented languages provide are user-defined abstract datatypes with our type discipline made less rigid via type polymorphism. That still leaves much room for the programming language designer to determine the details of the type system, picking a compromise between simplicity vs. safety vs. expressiveness/flexibility.

    The controversial part of OO is the mechanism for describing the implementation of one kind of object in terms of a related object’s implementation. The notion of inheritance combines implicit delegation (delegation from the object of the subclass to an unnamed implicit object of the superclass that it contains) with type polymorphism. I think language designers should have made this sort of implicit delegation more explicit (and flexible), and provided a separate, orthogonal construct for expressing the polymorphic subtyping.

    It seems that the pioneers of object-orientation were more concerned with behavioral semantics (“look at what my programs can do”) than with denotational semantics (“look at what these programming language features _mean_”).

    Related joke: “I learned reading via word recognition rather than by relying on phonetics. This leads to amusing errors sometimes, like when I confuse `data-warehousing’ with `data-whorehousing’. What is data-whorehousing, you ask? It’s a technique often used along with sex-object oriented programming.”

    Comment by fsilber — 2010/09/13 @ 17:31

  12. I really enjoyed reading this post, from the first to the very last word. Assessing “the model as being the source code” sounds a bit weird to me however – although I like what’s weird in general. It’s only a general feeling but I really don’t expect it to be the path OOP should go. Modelling is good for data, not for processing. The (only) design pattern I like to follow is the KISS one (Keep It Simple and Stupid). Optimization has long been forgotten for the sake of impressively useless complex designs and claim their beauty and pureness. After all we have so much resources now, why should we care about memory, disk space and CPU usage? What if “640KB ought to be enough for everyone”?

    One thing is sure on the other hand: Smalltalk is one of the only languages I don’t know yet (along with Lisp) and I’m now really willing to dive into it.

    By the way, you didn’t mention the OOP-like way of programming – the event-oriented one, may this be MS Visual Basic, MS MFC or Borland Delphi.

    Comment by Fabien Bouleau — 2010/09/13 @ 23:32

  13. Fabien Bouleau asked about the OOP-like event-oriented way of programming. This was another case in which hackers came up with a scheme that worked but couldn’t think of the right way to explain it. Thus, we get people overloading the word “event” to mean: (a) something that happened, (b) a notification that something happened, (c) a type of thing that can happen, for which your code can provide a handler to react when it does, or (d) a place to store your event handlers. The result is just meaningless jargon, as in one C# book which instructed readers to “add the delegate to the event” (you mean like “increment the explosion via the first-responder passed as the input argument”?). The only way a programmer could move from text-based systems to the presumably magical GUI-based system was by playing around with sample programs to see what happens when you do certain things.

    Instead, we should have had a description of the way the operating system converts GUI actions (events) into messages in a message stream while the program reads the message stream and, in response to each message, calls a procedure which may do any combination of (1) computing, (2) issuing commands to the GUI, or (3) adding its own messages into the message stream to be processed later. To someone who has programmed in conventional languages, that’s an explanation which makes sense.

    Comment by fsilber — 2010/09/14 @ 21:52

  14. “I challenge you, however, to name a *single* programming language mechanism that supports change.”

    update-instance-for-redefined-class

    Comment by Faré — 2010/09/15 @ 07:15

  15. … and YES, I have used it. See my ILC’2010 paper on ASDF 2.

    http://common-lisp.net/project/asdf/ilc2010.pdf

    Other example: Erlang’s syntactic distinction between static calls vs dynamic calls, which supports hot upgrade of code.

    Comment by Faré — 2010/09/15 @ 07:20

  16. @Faré: Actually I mispoke. I intended the challenge to apply to *mainstream* programming languages. Both Lisp and Smalltalk support class extensions, for example, which are very nice mechanisms to support change. Other examples abound, but there are not so many in bread-and-butter languages.

    Comment by Oscar Nierstrasz — 2010/09/16 @ 18:14

  17. Dijkstra was clever, but he complained pretty much about everything. Find something about computers that you’re passionate about, and you can be damn sure he complained about it ;-)

    Some of the things you mentioned are flaws of specific OOP languages. Fragmentation and “my-language-is-better-than-yours” seems to have more to do with human nature. It happens with procedural and functional languages as well. And flamewars between fans of static vs dynamic typing are the norm.

    Finally, I don’t agree that OOP makes programs “harder to understand” than procedural programs. *Simple* programs are straightforward and easy to understand, of course — then again, so are *simple* OOP programs! Back in the real world, however…

    Comment by Andrés — 2010/09/19 @ 16:32

  18. Oscar: what about JavaScript, by the way? It’s a mainstream language for the web, with prototype-based OOP… which supports change!

    (though not a lot of people are aware of the full power of JavaScript)

    Comment by Andrés — 2010/09/19 @ 16:42

  19. Great talk!
    I especially like that it summarizes so well many of the ideas that new languages should try to avoid.
    Are you familiar with scenario-based programming (SBP) and the language of Live Sequence Charts (LSCs)?
    http://www.wisdom.weizmann.ac.il/~dharel/papers/LiberatingProgramming.pdf

    It is interesting to test in light of your mentioned points, since it is very different on many respects, and it avoids many faults that way.
    There is no paradigm yet, or you could consider the whole idea of SBP a new paradigm.
    Since OOP is so mainstream, it is still not widely used and therefore not condemned yet. Then again, maybe being condemned is a good think…
    It has the concept of classes, allowing to refer to groups of objects of the same class symbolically, which is closer to the idea of classes in our mind.
    Methods and types, still remain part of the language, but they are hard to get rid of, but methods in LSCs are used as messages between objects.
    The language is incremental and supports change easily.
    Design patterns and methodologies are not part of the language yet, but if it will be widely used, they will probably appear, since they are something that grows with the language, again, maybe not too bad…
    LSCs is taking a subset of UML, extending it, and making it executable. Making the model be the ‘source code’ or rather, the implementation.
    Is it the next new thing? Who knows, but to be that it needs to be combined with OOP at least as a transition, since OOP is around for too long.
    Thanks for this great summary.

    Comment by M. Gordon — 2010/10/05 @ 05:24

  20. Thanks for your thoughtful article.

    As a database guy, I have another beef with OO: I abhor defining data structures around the accessibility limits of an OO model — i.e. “We’ll have to flatten this data so we can get to it.” Or “How do we cross over that link class?”

    In my environment, this occurs because a multi-dimensional web of data is represented as a set of trees that only can be accessed in one direction. Directional access limits potential functionality. It also obstructs changes that use data in a different direction or along another path. Due to tree limits, our OO programmers spend significant time wrestling with potential access issues. What a load of complications!

    Comment by R. Waymire — 2010/11/12 @ 00:22

  21. I do not know how Dijkstra came about object-oriented programming was invented in California (I know these statements of him are tongue in cheek). I hope everybody here knows that object-oriented programming was invented in Sweden.

    Comment by Jurgen Defurne — 2010/12/01 @ 13:50

  22. The Norwegians will be surprised to learn this, I think.

    Comment by Oscar Nierstrasz — 2010/12/01 @ 15:09

  23. Although I can’t agree with even half of your arguments (a lot of which are already replied to in previous comments) I do share your pain that somehow OO still feels too limiting. Personally I think C# and C++ have major advantages over Java. (e.g. proper generics)

    While thinking about how I would ideally like to code I found out about Language Oriented Programming. This really nice article explains its paradigm. It’s like DSLs on steroids.
    http://www.onboard.jetbrains.com/is1/articles/04/10/lop/

    I really like the ideology of LOP and am toying around with MPS by JetBrains lately. So far I only have one big complaint and that is that it still is java-oriented. LOP principles do allow for extension to any existing or new language but MPS hasn’t advanced far enough for that yet.

    Comment by Steven Jeuris — 2010/12/10 @ 01:34

  24. It seems to me that you might have let your education get in the way of your learning.

    1. “Programming is Modeling” is absolutely right, but I don’t know if we mean the same thing. I design objects to represent resources and actors: this way, I am working with a symphony of nearly tangible objects to produce my desired result. I go see the actor responsible for making an action happen, or look at the resource that knows about a specific point of data. The focus is on mapping the problem domain so that I can speak in those terms when I’m developing.

    2-5. I think you are way too hung up on very specific implementations and designs to solve problems and meet needs that admittedly aren’t amazing. Your observations are valuable but far too specific to be useful considering the more general notions you are on to. I support what you’re saying, but the bigger picture needs attention.

    6. This is probably the most important thing you’ve pointed to! This made me very excited to read and happy to know that others are thinking about this problem, too. I don’t want to get ahead of myself, but I’m using a simple form of the decorator pattern to decorate specific resources in an API I’m iterating on in order to modularize changes for testing and reuse. I’m fairly pleased with the outcome, though having change be an integral part of the tools we use would be far better.

    7. Here I think you’re hating on something because you’ve focused on the wrong thing. If we’re using the language to model our problems and find ourselves implementing theoretically equivalent code, we’ve got ourselves a design pattern! It just happens sometimes, and is a natural part of good design: we become consistent and use good designs to solve our problems, and sometimes those reflect these well known design patterns, and sometimes we’ve created new ones.

    You say some great things, and you touch lightly on a lot of really important disparities and principles, but I feel like your letting your rant get in the way of the gold you have to share.

    Thanks for sharing :)

    Comment by Matt Todd — 2010/12/10 @ 11:45

  25. My understanding of Alan Kay’s definition of OO is that of a computational semantics (not a paradigm for programming). Computation is message passing in OO languages, just as computation is function application in functional languages.

    That’s why he dislikes Java and C++. They just bundle some data together and have some virtual method lookup. Most computation in Java happens within a method, which is just a series of procedural statements.

    Comment by Eric Normand — 2010/12/10 @ 13:38

  26. Er…regarding change, have you not heard of refactoring? There’s a whole camp of people for whom constantly reorganizing your code (using automated tools, of course) is very important.

    I learned OOP as being “Encapsulation, Polymorphism, Inheritance,” which seems pretty reasonable, and I can’t think of an OO system that doesn’t have those things (although of course you could write one).

    I’m not really sure what you’re ranting against. One minute it’s OO, the next it turns out it’s actually the failure of IDEs to show us code execution cleanly (I’m not sure you’re up to date on modern IDEs, but in this respect you’re right), and then you’re harping on things that are actually failures of language design–the frameworks needed to make modern C++ and Java usable. Except those are also libraries of common functionality! Like in C!

    And then you’re complaining about type systems in an OO article. Are C and Pascal’s type systems so well-done and usable that this is an OO thing?

    Maybe you’re cranky about people’s over-enthusiasm for OO, which, as such, ended about 15 years ago as everyone calmed down. There are rants like this from the 80s about OO, and from the introduction of structured programming before that. It’s just as misdirected now as it was then; I’m just shocked to see it in 2010, when almost all of us view OO as just another way to organize code (sometimes in a quite procedural manner). The world has moved on.

    Comment by Chris D — 2010/12/10 @ 14:54

  27. Jurgen,
    Dijkstra said that object-oriented programming was invented in California because Smalltalk, the first OO language, was invented at Xerox PARC in Palo Alto, California.

    Comment by JohnH — 2010/12/10 @ 18:23

  28. Great insights!

    Not just because this post emphasizes on how tough OOP is, but because you can get this sense of how complex and difficult programming in general actually is.

    I’ve read most of the responses and I’m getting this certain vibe of people oversimplifying things – as if the current state of programming tools and technologies is adequate when confronting very complex problems. Well, it is not!

    In my opinion instead of oversimplifying things all programmers and software engineers should acquire this healthy skepticism, because most of the stuff is just buzz – either it works only in scenarios with limited complexity or it requires 10 years of practice to just get some sense of the tool or paradigm at hand.

    I really like the author’s suggestions and there are certain efforts in these directions.

    For example, I really find fascinating the work of Gregor Kiczales in the field of adding some “real-world sloppiness” as part of the programmatic effectiveness. A year ago I wrote some sort of a thesis on this topic and it would be great if you find the time to get through these ideas (which probably aren’t new at all to you).

    Formality vs. Informality

    Comment by Vladimir Tsvetkov — 2010/12/10 @ 19:37

  29. Hey Vladimir Tsvetkov,

    I read you mentioned “Meta-Object Protocol for Lisp” in your post about formatility vs. informality.

    While I haven’t checked this out yet, a quick look at it makes me believe it has some of the same principles as mentioned in the Language Oriented Programming article. Actually, it might follow the same paradigm. I’m sure you’ll find it a very rewarding read if you haven’t read about it yet! The main difference I see is that the CLOS still limits itself to “modelling” in text source. The revolutionary thing of MPS is that theoretically, it supports any best suiting representation of your model, as code isn’t stored as source files anymore. (“Programming is Modeling”, as the author of this article mentioned.)

    “I challenge you, however, to name a single programming language mechanism that supports change.”

    This is exactly the problem I was trying to find an answer to, which is how I ended up at LOP.
    http://whathecode.wordpress.com/2010/11/19/language-oriented-programming/

    Comment by Steven Jeuris — 2010/12/12 @ 17:31

  30. There is a langage where the model is the code, Scade:

    http://upload.wikimedia.org/wikipedia/commons/9/99/SCADE-cruise-control-design.png

    Comment by nicolas — 2010/12/14 @ 12:25

  31. 1. There are class-oriented languages (java) and object-oriented languages (these are rare, javascript is an example). People mistakenly call them all object oriented, but that’s not really accurate. I would say OOP is about controlling objects and objects contain state and behaviour.
    2. Yes, language beauty is in the eye of the beholder.
    3. Think of class as short for classification. Objects are examples of their classification, not equal to their classification. Just like a rabbit is an example of an animal, not the definition of one. That is not a hard concept to get.
    4. Based on your complaints, I think you really mean functions as well. So ok, everything is a top to bottom script in your world. Best of luck with no code-reuse.
    7. OOP has documented idioms called Design Patterns. You can argue that they are over-hyped and prone to zealotry. But remember that all programming styles have idioms.
    5,6,8,9,10 All of these are orthogonal to OOP

    Comment by Tim — 2010/12/15 @ 04:12

  32. Dijkstra was wrong, object-oriented programming was invented in Norway by Kristen Nygaard in the early 1960′s with the SIMULA programming language.

    Nygaard drew his inspiration from Marxist ideology and regarded OOP as a means of advancing socialism through the medium of computer programming. The theoretical underpinning of OOP is the philosophical foundation of Marxism, so if you want to understand what OOP is, study dialectical materialism.

    And if you want to understand what is wrong with OOP, study what is wrong with Marxism. If you travel far enough down that road you will find that Marxism is ultimately rooted in Kantian subjectivism. This explains why OOP is essentially anti-conceptual in nature.

    The Marxist means of forming abstractions is characteristically model building rather than concept formation. Models are related to reality by means of an approximate similarity relation. Reality is conceived as having no definite nature and always being in a state of flux.

    Concepts on the other hand, are related to reality by means of an identity relation, with the assumption that reality has a definite nature that determines and delimits cause and effect.

    The architectural efficiency of models vs. concepts is different. Models break down when scaled up in complexity due to the cumulative effects of not being exactly mapped to the things that they are supposed to model, sort of like the logical equivalent of what happens with round-off error in floating point calculations when carried beyond certain limits.

    This means that as the world’s software infrastructure increases in complexity there is increasing pressure to move from model building to concept formation, and from information hiding toward information visibility and organization. There is thus a fundamental shift emerging in the principles of integration used in building complex systems. The future belongs to concepts because nothing else can do the job.

    Comment by Tim Lee — 2011/01/06 @ 22:35

  33. The object-oriented paradigm is frustrating to understand due to its essential nature as an arbitrary system of anti-concepts.

    It is helpful to consider another such arbitrary system, this one from the field of economics. It too is a system of thought constructed according to the subjectivist model building approach of Kantian philosophy.

    Here’s what an economist said about this type of thinking: “In the final analysis, however, Keynesian theory is a set of mutually reinforcing but jointly unsupportable propositions about how certain macroeconomic aggregates are related to one another. Keynesian policy is a set of self-justifying policy prescriptions.” — from “The Trouble With Keynes” by Roger W. Garrison.

    The object-oriented paradigm is also a set of mutually reinforcing but jointly unsupportable propositions about how software should be designed. It is an elaborate castle in the air.

    The object-oriented theory does not start from the objective nature of computers and the human mind, and then build accordingly from there, rather, it is fantastic wish-fulfillment projection originating in the mind of a subjectivist.

    That is why, for example, it is so important to the object-oriented theorist to hide information, raising information hiding to the status of a “principle”. Information must be hidden and protected against because natural reality is the enemy of those who crave the arbitrary. The object-oriented paradigm is inherently nihilistic due to its origin in subjectivist philosophy.

    See “Introduction to Objectivist Epistemology” by Ayn Rand for an analysis of what is wrong with Kant’s philosophy.

    Comment by Tim Lee — 2011/01/22 @ 21:36

  34. Is there a language, where the model is the code?
    What is Scade?
    What about UML?
    What is the difference between model and code?
    Is model something graphical and code something textual? Or is any formal representation of the real world a model, somehow?
    You hate OOP? – I love this discussion!

    Comment by Siegfried — 2011/01/25 @ 14:43

  35. I agree with you but I love OOP too, I enjoyed reading this post, incredible, over March of 2011 and yet we have a lot of doubts about the effectiveness of OOP.
    Close to the natural language? did you make the base class library?, How it is possible to understand it? OOP is like a trick or an artifact to programing computers, but tomorrow everything will be decorated with [_ ] =>;
    beautiful.
    First, human understanding, readability, please.

    Comment by Fernn — 2011/03/11 @ 03:12

  36. When we programmed in assembler, we used OOP. We didn’t call it that and we didn’t have any support from the assembler, but we thought of the data records as being “things” with their own existence as units and we knew that various subroutines had no sensible function when called with the “wrong” data on the stack (or being pointed at). One common type of subroutine was one that made a copy of an existing object in memory.

    Object oriented programming is actually quite a natural way of working and eventually someone started writing languages that helped with the process, in particular memory handling. Essentially, we ask the language to enforce the rules that we once enforced on ourselves to try to keep the complexity down.

    Thing is, of course, no one really agrees on where the line is between “helping” and “suffocating”.

    These days, when I programme for fun, I use Forth and build the OOP features I need for the task at hand (or just for the sake of trying different ideas) using the language’s language-defining features. Generally I end up with something much more like Smalltalk rather than C++, so perhaps I should make a serious effort to learn Smalltalk at last.

    Much as I admire Dijkstra, he suffered badly from Ivory-Tower syndrome hating anything that made computing practical if it cost anything in rigour. But my clients at work want functionality and they don’t have a government grant to pay for years of conferences and hotels and meetings and formal proofs. They want to take an on-line booking for their training courses and they want to do it this month.

    Dijkstra’s bad-tempered complaints about saving Computer Science from itself was the product of never having to actually do it in the real world. Sometimes being correct is not the same as being right.

    Comment by Thomas Worthington — 2011/04/30 @ 00:09

  37. Do you have what it takes to survive a software zombie apocalypse?

    Worst-case Scenario: The news reports an object-oriented programming infection.

    What do you do?
    A) Run.
    B) Fire all the engineers with Scandinavian last names, just to be sure.
    C) Stock up on quinine tablets, memory maps, beef jerky, and a copy of “CMOS Cookbook”.
    D) All of the above.

    Wait a minute, wait…

    Here comes an OOP zombie right NOW!

    The hands are outstretched, the eyes… empty sockets…

    …it shambles right into your cubicle, opens up its maw and moans:

    “MuSt… dEsTRoy gLoBalS… Encapsulate::Everything… BRAINS! GIVE ME BRAINNNSSSS!”

    [FADE TO OPAQUE]

    SNAKE PLISKEN (V.O.) “We saw this coming back in ’87. No one took it seriously.”

    – George Butler

    Comment by George Butler — 2011/05/08 @ 19:27

  38. Great article.

    And you are just touching the surface. You need to dig for the creators of OOP. You will be very surprised to see what people love now. Was nothing to do with OOP today. In fact their goal was to make complex systems. And they needed a better way to deal with variable scope. The whole idea of hiding information is actually pretty silly. Why hide information if it really just needs to be in the right place. Who are we protecting and what is the price we pay for it?

    We really need some fresh ideas in this profession.

    Comment by Arturo Hernandez — 2011/06/30 @ 07:33

  39. [...] reflect the truth behind OOP. This reflects a slight change from his previous blog on that topic (Ten Things I Hate About Object-Oriented Programming): Oscar now agrees Object-Orientation is indeed a paradigm. I buy Oscar’s claim that the [...]

    Pingback by TOOLS Europe 2011 – Day 1 — The JOT Blog — 2011/08/04 @ 17:55

  40. Let’s simplify this … low-level languages > high-level.

    OOP is dead.

    Let’s move on.

    Comment by Andy Harglesis — 2011/11/10 @ 05:27

  41. I think the O-O idea is actually pretty good.
    What went wrong was giving the development to ins… consulting companies that sell tools.
    That directed the whole development towards selling features instead of working base.

    The worst thing is trials of mathematization of O-O:
    One of the basic rules that makes math work is “two sets are identical if their elements are the same!”. That means: The female presidents of United States are flying cows (both sets are empy). Design a class (object) structure of that.

    Obviously O-O is based concepts – that is: on language.

    Comment by Turboscrew — 2011/12/13 @ 13:50

  42. [...] But let’s dissect OOP from a pure abstract view (courtesy of The JOT Blog): [...]

    Pingback by What’s Wrong with OOP? « Linux Philippines — 2012/01/03 @ 10:04

  43. I think only frustration not understanding the “true” oop let you write this rant. Without OOP is chaos. Procedural programming is chaos. OOP is abstraction, not everyone use/understand abstraction. Look at the software engineers and how they “love” mathematics. Soo… things in life are not that easy to understand…

    Comment by adi — 2012/01/06 @ 23:56

  44. The article from Kent Beck is the modern version of coding in the debugger from Minsky see http://c2.com/cgi/wiki?ProgrammingInTheDebugger (middle of the page)

    being in context. ain’t nothing like it!

    Comment by agumonkey — 2012/01/07 @ 00:11

  45. Nice article. But I think that Smalltalk is the best OO language in the world.
    I especially agree with your 4., 5. and 6. point. But they are especially true for C++ and Java but not so much for Ruby and C# and even less for Smalltalk.

    I think what Alan Kay tried to do with Smalltalk (see http://himmele.blogspot.com/2010/11/alan-kay-on-object-oriented-programming.html) does not solely depend on the programming language.

    …maybe we should all switch to Erlang :-) .

    Comment by Himmele — 2012/01/07 @ 00:51

  46. Oscar, I just saw this via Hacker News. Thank you for explaining why I loathe doing OOP, in particular via section 3 on classes vs. objects; I no longer wonder whether I’m an idiot who just doesn’t have the mental capacity to “get it”. Oh, and I hope to return to functional programming (which is where I started thanks to APL — it’s not purely functional, but the purely functional part is what everyone likes).

    Comment by Rohan Jayasekera — 2012/01/07 @ 02:23

  47. Wrong: programs = functions + functions
    Correct: programs = functions(functions(programs), functions(programs))

    Comment by Dave — 2012/01/07 @ 04:32

  48. I’ve seen some instances of OOP done really bad/wrong. I’ve also seen some projects where it’s been done so well, that the architecture is clear and understandable, and the code reads like a good book (for instance, see ns-3, written in C++).

    Comment by Lalith Suresh — 2012/01/07 @ 23:37

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress