6

Steve yegge wrote an article called "Execution in the Kingdom of Nouns" back in 2006, 14 years later I still find the points he made valid. For example, "Action is what gives life its spice... (but) Object Oriented Programming puts the Nouns first and foremost ... nouns are things, and things are prized beyond all actions in the Kingdom of Java".

The example he used still resonates with me. Most of time when I write the a piece of codes to do a task, it normally consists of a serial of actions. Using his example of taking out the garbage to illustrate the the point,

  /*To take out the the garbage*/
  get the garbage bag from under the sink
  carry it out to the garage
  dump it in the garbage can
  wash my hands
  get back to my couch
  ...

what I need here are a serial of actions, not a serial of nouns like

A GarbageDisposalStrategy nouns, 
A GarbageDisposalDestinationLocator nouns for finding my way to the garage, 
A PostGarbageActionCallback nouns for putting me back on my couch.
...

I have seen too many codes with all kinds of manager classes, with public methods like run(), execute() or dothis().

And let me give a more realistic example to further illustrate my point. People always say choosing the right paradigm for the right problem. So let's take web development as an example. In web development we have lots of OOPs and frameworks, not just in java. But even since I use nodejs (express) to do web development I never use OOP, never miss it. Express's middleware is just a function chain.

So both OOP and procedural design work well for web development. But with express I feel far more easier, I spend more time in developing the "real" code instead of learning the frameworks and all the design and twist in the framework.

What is the "right" paradigm for web development?

What are the disadvantages of OOP, especially in java (in web development & in general)? Does OOP overemphasize the importance of noun and thus put action/verb in the less importance position ?

I also need to emphasize that my question is not to discuss/promote functional programming or to start a language war. I am fully aware that my question maybe seen as opinion-based or too broad. But the fact that 14 years later the problem is still here makes me ask this question.

---- update ----

One more vote and my post will be deleted. But please, the future readers, don't vote to delete it, it has been closed, why delete it? I do think it raises a valid concern, why delete it?

Although my question was closed (as I expected) I want to point out that there was a same question at stackoverflow (before I changed my question title), which was also closed https://stackoverflow.com/questions/2853316/disadvantage-of-oop

There are some good answers there so if you have interest take a look. An answer I quite agree is (maybe because many of my codes are transformative processing)

OOP works best with large-scale, multi-developer, multi-module projects. For "development in the small" - such as scripting or transformative processing, it can require a good deal of overhead without necessarily adding value.

...

transformative processing is quite amenable to the functional style of programming

PS, if you think Steve yegge's article is gibberish, you may check Joe Armstrong(father of erlang) article Why OO Sucks, much shorter, straight to the points and yet basically made the same arguments, like "Data structure and functions should not be bound together."

Qiulang 邱朗
  • 3,095
  • 3
  • 13
  • 22
  • 3
    I think Alan Kay would strongly contest the notion of OO being about nouns - https://softwareengineering.stackexchange.com/questions/46592/so-what-did-alan-kay-really-mean-by-the-term-object-oriented – Ben Cottrell Nov 18 '20 at 15:05
  • My opinionated 2 cents: Note when people write procedural code, often it *isn't* written it as described in the "To take out the the garbage" example. Instead, it's written in terms of even smaller steps, in terms of concepts that are at a lower level of abstraction. E.g., the "get the garbage bag from under the sink" bit is written as some obscure-looking sequence of instructions. Many people don't wrap that into `GetGarbageBag(sink)`, and it stays that way - with no explicit separation of concepts or control over unwanted accidental coupling, which happens as the code changes and grows. 1/3 – Filip Milovanović Nov 18 '20 at 17:37
  • But even if they do, as the code grows further in scope and complexity, it often doesn't occur to people to do it again. They never make the `TakeOutGarbage()` function, even though they may leave the `// take out the garbage` comment above that sequence. So they never come to the step where they change it to `TakeOutGarbage(then: () => GetBackToCouch())` because maybe they realized that this happens to be a better, cleaner design for their *particular problem*. Instead, it just gets more complicated and tangled. This is how you end up with 1000 line functions. 2/3 – Filip Milovanović Nov 18 '20 at 17:39
  • What I'm talking about here are abstraction skills, modeling skills. So far this had nothing to do with OOP specifically, it's more fundamental than that. But my point is, if you consistently end up with 1000 line tangled functions *without* OOP, then you won't be magically writing nice, clean code *using* OOP. Furthermore, you won't even be able to begin to see what the pros and cons of OOP are compared to, say, functional programing, and when and how to use one vs the other, etc. 3/3 – Filip Milovanović Nov 18 '20 at 17:39
  • All actions requires both tangible and intangible nouns to execute them. In the example of a get the garbage under the sink, you are missing a lot of steps that the single action requires which are being combined to perform this higher level action. (ex bend down, extend are arm, close fist, retract arm, stand up). Each of those actions have tangible nouns (ex. arms and legs) and are themselves combined into an intangible action (a strategy for getting the garbage from under the sink.) The actions being taken are the code, the nouns are how we organize the code. – yitzih Nov 18 '20 at 22:09
  • @yitzih that is why a simple task becomes a complicated design. – Qiulang 邱朗 Nov 19 '20 at 02:01
  • Of course, asking "what are the disadvantages of OOP? is going to get closed. OOP is a tool. Sometimes it is the right tool, some times it isn't. If we want to know if it is a good tool, we need a task you want to solve. Besides, it is sad that Java's brand of OO is considered the default. However, Java has some functional features now. It isn't OO vs Functional either. There are other approaches even if less popular. Data driven, and logic programming come to mind. I also want to recommend "Functional Principles for Object-Oriented Development" by Jessica Kerr, if you can find it to watch. – Theraot Nov 23 '20 at 05:14
  • Its is not surprising that nouns are used so much. Look at any English sentence, or just pick another human language. How many verbs to objects does it contain? All valid sentences contain a verb (no more, no less) (and yes I'm excluding conjoined sentences). But all sentences have at least one noun, usually two, and often more when we throw in prepositions. – Kain0_0 Nov 23 '20 at 05:24
  • Here: [Functional Principles for Object-Oriented Development](https://www.youtube.com/watch?v=cpyrTkzXeL8). You may also be interested in [The Best Refactoring You’ve Never Heard Of](https://www.youtube.com/watch?v=vNwukfhsOME) (audio issues, but there is no better version). More fodder for you: [Boundaries](https://www.destroyallsoftware.com/talks/boundaries) when it talks about paradigms (10 minutes, 18 seconds). – Theraot Nov 23 '20 at 05:34
  • @Theraot I can get it was close but I don't get why people want to delete it! It trucks me as some neat freak can't tolerate a different opinion, just like Steve yegge's article said. – Qiulang 邱朗 Nov 23 '20 at 06:02
  • Yes, some people don't want to listen to what they don't agree. Yet, I doubt they think they are not listening. I'm no fan of Java, but I don't think the example in article are representative of good use of it. Btw, I see is a vote to reopen. I'd probably vote that too if you narrow this. Disadvantages compared to what? For what? - Most would agree that doing everything OO is a bad idea. For instance, OOP is often procedural internally, as the StackOverflow quote suggest. OO always needs an agent/service. Does the garbage moves itself? `You.Get(What: Garbage, From: Sink.Under);` (Not Java). – Theraot Nov 23 '20 at 06:40
  • Actually the reason I asked this question is I have been doing nodejs for couple years and I barely touch oop at all, object based sometimes. I also write some python scripts, not oop at all either. So if I narrow it I need to think about how, give me some time (before it is deleted). Thanks for comments. – Qiulang 邱朗 Nov 23 '20 at 06:47
  • For once, you could delete your question yourself, and post a new one. However, just the same question would not only not work, but would not be well received to just re-post it. Trying to look at questions on the same vein, I find most are closed. Perhaps a chat room to talk about it? We are already making a long conversation here as it is. Edit: at least there are some open questions of the form "what paradigm to choose for XYZ" and "What's the benefit of this paradigm over this other". Made a room: https://chat.stackexchange.com/rooms/116551/conversation-on-the-kingdom-of-nouns – Theraot Nov 23 '20 at 07:15

2 Answers2

17

One of the problems with OOP is not what OOP is, but how it is taught.

Alan Kay, who coined the term "Object-Oriented Programming" has made it very clear on multiple occasions that Messaging is the most important thing in OOP. He has even said that he regrets called it Object-Oriented and should have called it Message-oriented instead.

So, even from the very first days of OOP, the focus has been on the Interaction, not on the Thing.

However, the very first technique for object-oriented analysis being taught is "underline all the subjects, verbs, and objects in the use case; the subjects become classes, the verbs methods, and the objects fields."

Note how this methodology does not even focus on objects, it focuses on classes.

But even if we assume that this methodology is a good methodology, you can still end up with widely differing designs, depending on how you formulate the use case.

One of my favorite examples is banking. The BankAccount is one the most-widely used introductory examples in OOP. And "everybody knows" what a BankAccount is, right?

class BankAccount {
    private Money balance;

    void deposit(Money amount) {
        balance += amount;
    }

    bool withdraw(Money amount) {
        if (balance < amount) { return false; }
        balance -= amount;
        return true;
    }
}

Easy-peasy. Now, add the transfer method. Oh, wait, what object does it belong to? Does A transfer to B or does B transfer from A? And what about concurrency?

class BankAccount {
    Money balance;

    void deposit(Money amount) {
        balance += amount;
    }

    bool withdraw(Money amount) {
        if (balance < amount) { return false; }
        balance -= amount;
        return true;
    }

    bool transfer(Money amount, BankAccount target) {
        if (balance < amount) { return false; }
        withdraw(amount);
        target.deposit(amount);
        return true;
    }
}

"Everybody knows" that "balance" is data and "transfer" is an action. Right? RIGHT?

Well, turns out that's not how it works. In fact, it has never worked that way, all the way back to when bank transfers were first invented.

What happens when you make a transfer is that the clerk writes a transaction slip, and at the end of the business day, all the transaction slips for the account are tallied up, and this yields the new balance. Then, the transaction slips are sent to the receiving bank, where the same thing happens.

So, in the "real world" (which every OOP tutorial teaches us we are supposed to model), the transaction is actually data and the balance is actually an operation!

record Transaction(BankAccount source, BankAccount target, Money amount)

class BankAccount {
    Money balance() {
        // find all transaction slips which have `this` as either source or target
        // add all the amounts which have `this` as target
        // subtract all the amounts which have `this` as source
        return result;
    }

    void deposit(Money amount) {
        TransactionLog.append(new Transaction(CASH, this, amount));
    }

    void withdraw(Money amount) {
        TransactionLog.append(new Transaction(this, CASH, amount));
    }
}

Note that all of our concurrency problems go away: BankAccount is immutable, Transaction is immutable, we only need an "almost-immutable" append-only TransactionLog. We also get a full audit-trail for free, and can recover from partial data loss.

That is not actually surprising if you consider that this is how banking has been done since the times when moving transaction slips via horse courier between branches and banks was risky and may have taken days. This has exactly the same problems and properties as a distributed electronic banking system.

So, as you can see, we can flip the roles of nouns and verbs for the exact same problem just by approaching the problem differently.

Also, note how the complexity of the problem and the context requires having multiple independent concurrent actors, namely at least the two branches of the bank. That is what OOP is supposed to be: multiple independent actors collaborating by exchanging messages while keeping their own workings hidden from the rest of the world.

Jörg W Mittag
  • 101,921
  • 24
  • 218
  • 318
  • Alan Kay also said that everything is the same (the "cells"). There is no "data" in OO, there are only objects. – Robert Bräutigam Nov 18 '20 at 15:10
  • 3
    Using the example of "taking out the garbage", would you append to a `TrashactionLog` instead? – Duroth Nov 18 '20 at 15:30
  • I know what you said, but your example didn't change the fact that noun is the king while verb is the second-class citizen if I may argue. – Qiulang 邱朗 Nov 19 '20 at 02:18
  • You may also check this https://stackoverflow.com/questions/2853316/disadvantage-of-oop (I have updated my question even though it was closed) – Qiulang 邱朗 Nov 19 '20 at 03:44
  • 1
    The example chosen here is utterly bad and detracts from the point. Why the heck would you use something specialized like bank accounts to answer a question in general? What has this general question got anything to do with bank account and transactions? – Pacerier Sep 18 '22 at 03:12
5

It's normal for people to think about a "series of actions" when thinking about a problem. It's easy, and anything and everything is under your complete control. Nothing wrong with that, it is just a way of thinking.

OO requires a completely different thinking though. Instead of command-and-control, you are actually encouraged to think of work as a cooperation among colleagues. It's not about "things", it is about living things. You give up control yourself in order to delegate tasks to other beings (i.e. objects).

To answer your question: The linked article is BS of course, or rather, it is a strawman. Sure, if you are doing OO very badly, plus you're overcomplicating everything, it will look pretty bad. Even if that applies to some frameworks or libraries, it's not OO at fault here, just people's wrong interpretation of it.

Robert Bräutigam
  • 11,473
  • 1
  • 17
  • 36
  • 1
    It's been a while since I read anything from Steve Yegge but IIRC he had a strong functional slant. This was written before Java supported passing functions. I don't think that there's much serious debate about whether function passing is a good feature any more but at the time of this article it was somewhat of a religious battle. – JimmyJames Nov 18 '20 at 17:30
  • Yegg's thesis is that Javaland (Java's interpretation of OOP) is wrong. and concurrently that noun elevation considered harmful. – Pacerier Sep 18 '22 at 03:18
  • @Robert, "is BS of course" meaning? – Pacerier Sep 18 '22 at 03:21
  • @Pacerier Hey, I'm not going to defend Java's OOP. They have JEE for crying out loud. What I do want to point out that his arguments seem to be against OO in general, arguing that the procedural way of thinking (his example of taking out the trash) is more natural, therefore OO is bad. I think the two are orthogonal. Object thinking *is* different. His OO examples are *not* OO though, they are a procedural programmer's view of OO. Admittedly a view that a lot of people share, but not a true picture of OO nonetheless. Does that answer your question? – Robert Bräutigam Sep 18 '22 at 18:16
  • @RobertBräutigam, iow you're saying the article isn't BS? – Pacerier Apr 11 '23 at 23:22
  • @Pacerier I guess it's just _misguided_. What he's criticizing is **procedural programming** done with OO-enabled languages. Some points are actually valid, it's just not made against the proper target, which is, again, procedural programming, not OO. – Robert Bräutigam Apr 12 '23 at 07:50