DEV Community

Cover image for OOP a software development mass psychosis

OOP a software development mass psychosis

Thomas Hansen on May 02, 2022

A broad layman's definition of a psychosis is roughly; "The belief in something that has been proven to be wrong". The definition of a mass psychos...
Collapse
 
codbugs profile image
Coding Bugs

Very nice article. I think you argue in a really good way but I disagree with you in almost all points. You said that OOP is not the unique solution and this is totally right. Depending on the problem you should apply the right solution. I mean, OOP is a way of structuring code and can be a solution for some problems. However, people not always apply OOP in the proper way and not always apply other solutions in the right way. That's why OOP seems to be a bad solution but could happen the same with other approaches.

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO • Edited

A broomstick is perfect because it doesn't need an instruction manual. Everything that's brilliant is intuitively understood without requiring further explanation. When I started coding (40 years ago), my very first creation was as follows.

10 PRINT "THOMAS IS COOL"
20 GOTO 10
Enter fullscreen mode Exit fullscreen mode

Reproducing the above easily understood program in (correct) OO would probably require an OutputFactory class, an OutputFactoryMarshaler class, a Main class, another OutputFactoryMarshalerFactory, with a couple of interface implementations to make sure it's adequately abstracted, another DoWork class, definitely inheriting from (at least) 2 or 3 distinct interfaces to apply by the rules of "SOLID", separating the implementation from the interface, allowing maintainers to implement alternatives through their IoC container, to prepare for scenarios that would highly unlikely never occur - And at the end of the day, I would have increased the requirements for cognitive energy by several orders of magnitudes to maintain it, effectively created "unmaintainable code", impossible to understand, debug, or extend in any ways what so ever - Paradoxically, because I wanted something that was extendible, easily maintained, and easily understood, with proper encapsulation.

I'm not sure who said this, I think it was attributed to Leonardo DaVinci though, and it goes as follows ...

Simplicity is the only brilliance

You can use OO to create great code, but the paradigm is implicitly making it much, much harder - Because the paradigm is fundamentally wrong. With OO, assuming you obey by SOLID, with the aim of creating "great code", it is fundamentally impossible to create even the simplest of "Hello World", without ending up with a "class hierarchy from the depths of Mordor" ...

Don't believe me? Port my above BASIC program (2 lines of code) to any OO language of your choice, and in the process make sure you obey by all the OO design principles, such as SOLID, clean architecture, etc, applying the adequate design patterns in the process where they make sense ... :/

Computing is a process of transformation. A process of transformation takes input, applies a verb to your input, and produces a result. The nature of our brains, and the natural laws of the universe you might argue, is much better geared towards using "verbs" as the mechanism to transform such data. Verbs are fundamentally better described with "functions", and not "subjects" (classes and types) ...

When that's said, I do a lot of work in OOP, simply for no other reason than the fact of that most other produce OOP code - I just try to avoid it every time I can avoid it ...

Notice, I liked your comment ;)

Collapse
 
anuragvohraec profile image
Anurag Vohra

Reality:

class Print{
     printInLoop(message){
        while(true){
           console.log(message)
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Anti OOPs Ranting:

Reproducing the above easily understood program in (correct) OO would probably require an OutputFactory class, an OutputFactoryMarshaler class, a Main class, another OutputFactoryMarshalerFactory, with a couple of interface implementations to make sure it's adequately abstracted, another DoWork class, definitely inheriting from (at least) 2 or 3 distinct interfaces to apply by the rules of "SOLID", separating the implementation from the interface, allowing maintainers to implement alternatives through their IoC container, to prepare for scenarios that would highly unlikely never occur - And at the end of the day, I would have increased the requirements for cognitive energy by several orders of magnitudes to maintain it, effectively created "unmaintainable code", impossible to understand, debug, or extend in any ways what so ever - Paradoxically, because I wanted something that was extendible, easily maintained, and easily understood, with proper encapsulation.

Thread Thread
 
polterguy profile image
Thomas Hansen AINIRO.IO • Edited

Even if that was true, the above is 7 lines of code. That is 3.5 times as many LOC as my 2 liner. Science shows us that the amount of resources required to maintain code is proportional to the LOC count. Your example is hence 3.5 times more demanding in both initial resources to create it and resources required to maintain it. One of OOP's sales pitches was "that it makes it easier to maintain your code". You just scientifically proved it wrong ...

Thread Thread
 
anuragvohraec profile image
Anurag Vohra

The ranting you did was , as I told none of them was required:

Reproducing the above easily understood program in (correct) OO would probably require an OutputFactory class, an OutputFactoryMarshaler class, a Main class, another OutputFactoryMarshalerFactory, with a couple of interface implementations to make sure it's adequately abstracted, another DoWork class, definitely inheriting from (at least) 2 or 3 distinct interfaces to apply by the rules of "SOLID", separating the implementation from the interface, allowing maintainers to implement alternatives through their IoC container, to prepare for scenarios that would highly unlikely never occur - And at the end of the day, I would have increased the requirements for cognitive energy by several orders of magnitudes to maintain it, effectively created "unmaintainable code", impossible to understand, debug, or extend in any ways what so ever - Paradoxically, because I wanted something that was extendible, easily maintained, and easily understood, with proper encapsulation.

Thread Thread
 
siy profile image
Sergiy Yevtushenko • Edited

@polterguy you're repeating a very common fallacy - less code is better. In fact, the amount of code is much less important (and in most cases just irrelevant). Also, this example does not show nor prove anything because it has zero useful functionality.

Collapse
 
wesen profile image
Manuel Odendahl • Edited

I'm not sure what the point of this article is besides being inflammatory. I am both a heavy user of functional programming and more traditional OOP languages.

My definition of OOP

There are many paradigms that get grouped under the name "OOP".

I think of OOP as:

  • "groups of method names are given a name",
  • "code that works on the same data can be reused", and
  • "groups of methods are kept close to the data they manipulate".

None of these are inherently bad, and they surface in different forms in functional programming languages too.

Task join/fork example in C++

You give the example of

join
   fork
      http.get:"https://gaiasoul.com"
   fork
      http.get:"https://servergardens.com"
Enter fullscreen mode Exit fullscreen mode

In a C++ framework I wrote (and I tend to be on the heavy-handed verbose side of the spectrum), I would write:

const auto ret = Tasks::join(
   m_Factories.HTTP->GET("https//gaiasoul.com"),
   m_Factories.HTTP->GET("https://servergardens.com")
).Start();
Enter fullscreen mode Exit fullscreen mode

If I wanted to push it, I could easily boil it down to

const auto get = [&](const string &s) { return m_Factories.HTTP->GET(s); };
const auto ret = join(
    get("https//gaiasoul.com"), 
    get("https://servergardens.com")
).start();
Enter fullscreen mode Exit fullscreen mode

which compiles to the exact same memory layout and binary code.

Because my HTTP factory implements an abstract virtual class, I can easily swap out different factories, say if I am running unit tests or decide to replace HTTP calls with some local IPC. I also get a concrete task object that I can pass around and introspect / monitor / listen to / cancel.

You might say that http.get : fun string -> bytes is more elegant than

class I_HTTPFactory {
public:
   virtual Task<bytes> GET(string s) = 0;
}
Enter fullscreen mode Exit fullscreen mode

but it is missing the point.

The value is that I get a clearly documented, easily extendable data structure that encapsulate what is needed to create thunks that ultimately return bytes. I can look at the class of my HTTPFactory instance and easily see that it contains say, a TLS certificate. I can also add a POST method, and make it obvious that both GET and POST belong together and reuse some of the same code and data.

These things are more opaque in a functional context.

Which is the best? None, they both work just fine.

OOP the strawman

Since you don't provide a concrete OOP API other than bringing up the strawman of needed an OutputFactoryMarshalerFactory to print out a single line of output, it is hard not to assume that you are arguing in bad faith. I can write

while (true) {
   println("I'M COOL");
}
Enter fullscreen mode Exit fullscreen mode

just as well. Bringing up LISP (all caps?), while Common Lisp has probably the most expansive approach to OOP of all the languages I know, strikes me as a bit odd as well.

Using C++ as an example, which is probably the language that I most often use to write what could be called "traditional OO", a class without virtual methods is arguably just a shortcut for a series of functions that take the same data structure as first argument. Once you introduce virtual dispatch, a class is just a way to combine a virtual dispatch mechanism with a data structure, give that group of dispatched functions a name, and make reuse easier. That's very similar to what many languages call "traits", arguably less flexible, but flexibility can often be a bad thing (say, if working in a big team with different skill-levels).

Data+Code centric patterns are useful

There's value in taking a data centric approach, especially in more resource constrained environments. I wouldn't know easily how much memory is allocated, when, where, by whom, and who owns it. In my C++, I know that I have 1 instance of Task_Join, 2 instances of Task_HTTPGet, and I can go look up the class to see that Task_Join keeps two pointers, and Task_HTTPGet a byte buffer, a state variable and a file descriptor. I know when they are created, I know when they are freed.

That data-centric OOP style might be less flexible than function-centric code when composing functions, but it's much simpler in many other regards. As with all code, it's about tradeoffs.

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

In a C++ framework I wrote (and I tend to be on the heavy-handed verbose side of the spectrum), I would write

Interestingly, the following code snippet you provided ...

const auto ret = Tasks::join(
   m_Factories.HTTP->GET("https//gaiasoul.com"),
   m_Factories.HTTP->GET("https://servergardens.com")
).Start();
Enter fullscreen mode Exit fullscreen mode

... is arguably more in the style of FP than in the style of OO. However, you didn't provide the creation of your m_Factories instance, you didn't provide the wiring of your IoC container (assuming it was somehow dependency injected), etc. But nice code - You're obviously skilled :)

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

Thx for the snippet. It took me a couple of days to realise I don't need to prove anything at all, since your C++ example basically is all the proof I needed ...

Collapse
 
tnypxl profile image
tnypxl

You can write heinously bad code in any language and with any design pattern. There is no approach or pattern that saves you from bad code.

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

Yes, but the general rule of thumb that seems to be valid "all over the place" is KISS, as in Keep It Stupid Simple - And if you follow KISS, it's much less likely going to produce bad code. OO is fundamentally incompatible with KISS. You're writing code for human beings, the fact that it compiles is just "a lucky side effect" one could argue. The simpler your code is, the more easily understood it is. OO results in complex code, FP results in simple code ...

Collapse
 
tnypxl profile image
tnypxl

Every word in this reply is wrong and I am embarrassed I didn’t catch it sooner.

But I’ll reiterate, FP isn’t going to save you from bad code by being inherently simple. For every statement that says it does, you can probably find 10 repos that use FP with hilariously bad results.

It’s never the language or the style, it’s always the person using it.

Collapse
 
devdufutur profile image
Rudy Nappée

There is no silver bullet... OOP and FP are no exclusive. I love FPing on my application code and agree with you on many points, but when I design library or use a 3rd party one I prefer to have well oop-organized packages/modules, class and methods rather than a bunch of functions.

Collapse
 
jwp profile image
JWP

Then why did even React use inheritance?

The entire .Net framework is OOP as is Java. None of those failed.

This is just a Javascript centric OOP Flame article. Problem is even Javascript supports OOP now.

NPM has messy Javascript code everywhere. It's a virtual garbage dump brought about by what Javascript allows and what people think are best practices.

Collapse
 
peerreynders profile image
peerreynders

Then why did even React use inheritance?

It didn't

// React 0.14.7 early 2016
var Example = React.createClass({
  render: function () {
    return (
      <div>
        <span>Hello</span>
        <span>World</span>
      </div>
    );
  },
});
Enter fullscreen mode Exit fullscreen mode

React.createClass(): "Create a component given a specification."

Component Specifications: "When creating a component class by invoking React.createClass(), you should provide a specification object that contains a render method and can optionally contain other lifecycle methods described here."

Clearly the React team wasn't immune to fashion influences as that factory function would have been more appropriately called React.createComponent() especially as for all intents and purposes the component instance's this.props and this.state were owned and managed by React - not the object instance itself as one would expect with standard class-based object orientation.

This style was advocated by Douglas Crockford as class-free object orientation at least as far back as 2008 (JavaScript the Good Parts).

The component specification simply contained what was unique about that particular component.

It was the later alignment with the ES2015 class template for creating objects that brought in extends React.Component.

Collapse
 
jwp profile image
JWP • Edited

For years this was common dude or are you too new?

class Car extends React.Component {

render() {

return

Hi, I am a Car!

;

}

}
Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

JavaScript has always had OOP, as long back as to the 1990s. It just didn't have class based OOP, but rather prototype OOP.

Collapse
 
jankapunkt profile image
Jan Küster 🔥

Which I even prefer over class based oop just to feel great by attaching my standalone function to a class' proto to stay dry but don't mess with inheritance.

And npm itself has no influence on Js as a language. Same issues can happen in other language registries too.

Thread Thread
 
polterguy profile image
Thomas Hansen AINIRO.IO

attaching my standalone function to a class' proto to stay dry but don't mess with inheritance

Very good point about dynamic features yes ... :)

Collapse
 
maxgoryunov profile image
MaxGoryunov

Very interesting article, but it is unforgivably wrong. The problem is not in OOP itself, but in the fact that all OO languages(and developers using them) come from imperative programming in the form of C. OOP is just as declarative as FP is. A lot of good concepts like immutability are not specific for FP only and they do not appear in its definition. The correct statement is "OOP is done wrong", not "OOP is wrong".

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

OK, I agree with that - It's still a problem ...

However, even though I blame OOP languages themselves in the header, I'm not really doing that in my arguments. Interestingly, most languages, including C#, is easily used in a "FP style" ...

Collapse
 
maxgoryunov profile image
MaxGoryunov

It might be interesting for you to look at EOLANG, an experimental OO language which is pure OO: everything is lazy, no flow-control statements(if and for), no classes, no METHODS, only objects and their composition. It feels very similar to FP because every object has a specific method "@", which is considered its primary method.

Thread Thread
 
polterguy profile image
Thomas Hansen AINIRO.IO

Interesting ...

Collapse
 
cyclotron3k profile image
Aidan Samuel

It would be great to have some real examples, or some side-by-side comparisons, instead of hyperbole like "virtually impossible to understand code", and "arguably the very definition of madness" which are not quantifiable, and "results in 1,000+ classes for something that could have been done with 5 functions in FP", which is not even true.

This article seems to be written for people who have already decided that they prefer FP. By writing stuff like the above, you don't win over any OO programmers, you just allow them to dismiss your whole article because you lead with things that are demonstrably false.

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

Thx Aidan, and yes, I have thought that exact same thought myself, as in provide for instance the "textbook example" from C# doing the same thing as my 5 lines of Hyperlambda code (in another comment), etc, then compare these side by side, to illustrate the difference.

Thx for the tip though, I'll definitely do that at some point in time when I've got the time ...

Collapse
 
thorstenhirsch profile image
Thorsten Hirsch

Thomas, it looks like your recommendation of programming languages is based on the lack of OOP rather than the functional features. Would you recommend against mixing both paradigms? I actually don't see a problem in it as long as one keeps the OOP very lightweight.

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

I guess I'm just trying to balance the debate here. I'm not "against" OO, I just believe one should be a bit cautious with it. The principles of SOLID, DDD and (overusing) design patterns, rapidly results in a code base nightmare, impossible to navigate or maintain ...

Collapse
 
michaeltharrington profile image
Michael Tharrington • Edited

Wow! I find this whole mass pyschosis thing super interesting and really enjoy how you tied this to the fallacy that OOP is infallible.

But yeah, I just had to look more into this mass psychosis thing...

From a wikipedia entry on "List of mass hysteria cases":

According to J. F. Hecker's 1844 book, The Epidemics of the Middle Ages, citing an unnamed medical textbook, a nun who lived in a French convent during an unspecified time in the Middle Ages inexplicably began to meow like a cat, shortly leading the other nuns in the convent to meow as well. Eventually, all of the nuns in the convent would meow together for a certain period, leaving the surrounding community astonished...[8]

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

Thought2 created a YouTube video about it. A must see ;)

Collapse
 
lexlohr profile image
Alex Lohr • Edited

Patterns like OOP can be applied to any problem, regardless if they are a good fit.

Patterns can shape your design decisions for the better or the worse. Use them wisely. Thinking of them as silver bullets is a recipe to shoot your own kneecaps.

Just to construct an example where OOP is a good fit: you have items with a lot of methods. Without OOP, you either need to externalize the methods or create them for every instance, which is bad for performance. With OOP, you can have the methods inherited and can even change them for instances that are already created.

Collapse
 
siy profile image
Sergiy Yevtushenko

Incorrect information in this article starts from the "30+" years. OOP is about as old as procedural programming (i.e. 50+ years). And it is just a logical next step: while procedural programming focuses on encapsulation of the code, OOP adds encapsulation of the data. All these are necessary steps to reduce software complexity.

I really like FP (and use it every day), but I'm pretty certain that real working approach is the hybrid of OOP and FP.

P.S. there are very little efficient pure FP algorithms for many everyday tasks, for example, sorting.

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

Pure functional and functional programming aren't (necessary) the same thing. OOP was "invented" in Simula 67, but it never went truly mainstream before the 90s ...

Collapse
 
siy profile image
Sergiy Yevtushenko

Procedural programming "invented" around the same time, but there were hot debates about it well in the mid of the 80s. The basics of agile methodologies were created at the beginning of the 70s, but agile went mainstream only on the mid of 2000s. And so on and so forth. This is just an illustration of how conservative software development is.

Collapse
 
kellychen04 profile image
Kelly

OOP is just one of MANY paradigms that you can apply, there is no hard set rule on when or where to apply, as always it depends on your context. You write your opinions about OOP as if they broke up with you!

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

You write your opinions about OOP as if they broke up with you!

Hahaha, kind of ... ^_^

Collapse
 
skinnypetethegiraffe profile image
Bobby Plunkett

I've seen both sides of the argument, and also have seen public opinion filp-flop between sides over the years (seems to cycle).

OOP and FP have their own sets of pros and cons. Some may be better suited for certain projects, architectures, or even developers personal preferences.

But to me, FP is not better than OOP, or vice versa. They serve a purpose, and it's the developers job to chose the one that suites their purpose best.

Collapse
 
wcravens profile image
Wes Cravens

I'm cracking up. I got here from the GraphQL article but this one is a gem too. I will add... almost all contemporary programming languages OO or otherwise are all sprinting to provide more and more functional paradigms with every release.

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

Hehehe, no sjiiit ...? :D

They're still a decade behind Lisp. Lisp was invented in the late 1950s ... ;)

Collapse
 
liamjoneslucout profile image
liam-jones-lucout • Edited

Seems a bunch of people are hating on you for this article, but I agree with one caveat: GO can also be written as an enterprise OOP nightmare.

Regarding OOP in general: my experience of it was one of constant inadequacy and corner cutting because of all the principles and patterns work

The worst sin for me in OOP is the "What if" fallacy. Want to write an application that needs to interpret a scripting language? Best make a factory that outputs an interpreter that follows an interface because you might want to swap Lua for Python one day!

Want a new class? We'll just make and interface for that too! You may want to abstract it eventually.

The amount of projects I've walked into where every class has an associated interface is shocking, and I'm not saying that is necessary for OOP, but it leads many programmers to that conclusion.

I used to be all about OOP, but ended up moving into full stack development with typescript and it's so liberating to just write what you need knowing that there no need for OOP principles. You don't have to write it, and nobody misses it (except the Java Devs). So suddenly you find yourself wondering : what was the point in all that boiler plate? What was the point in all those bloated projects where the behaviour is hidden behind 8 layers of abstraction? OOP has made the projects I've walked in to harder to maintain, not easier

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

what was the point in all that boiler plate? What was the point in all those bloated projects where the behaviour is hidden behind 8 layers of abstraction?

Hahaha :D

OOP has made the projects I've walked in to harder to maintain, not easier

Bingo! And at the end of the day, it's the only important thing to measure an idea around ... ;)

Collapse
 
jafarit profile image
jafar-it

I disagree with your stand. The concept you list are not inherently flawed but become one due to people taking them to a next level.
Mapping data with function is not necessarily bad if you think in the sense of Object.

 
peerreynders profile image
peerreynders • Edited

or are you too new?

Apparently you are "too new" because the React.createClass() factory function was the standard way (2013-05-29) stateful React components were created before React supported the ES2015 class syntax.

At the time a constructor function would have been the standard way of implementing a template for creating objects. That would have supported prototypal inheritance out of the box but there were other inheritance schemes around (combination inheritance, parasitic inheritance and parasitic combination inheritance).

The entire point of class-free object orientation was to get away from inheritance and use composition exclusively.

But the truth is that inside a factory function the React team could do whatever they wanted. ES2015 classes weren't supported until 0.13 (2015-03-10) which finally introduced React.Component (but of course IE never supported ES2015 classes in the first place).

React.createClass() wasn't deprecated until React 16 (2017-09-26) and the factory function was relocated to create-react-class.



James Coplien
"How many of you do object-oriented programming? What language? Java is the only language in which you cannot do object-oriented programming. Huh? Other languages. Smalltalk - no. C# - no. Python - no. No. Any JavaScript programmers here? Here are my object-oriented programmers - they're writing objects - the rest of you are writing classes."

Teaching OO: Putting the Object back into OOD (2003)
"Almost everyone who teaches object orientation uses the class as a fundamental building block. Such an approach misses the central point of object orientation: the objects themselves, and what they portend for flexibility and effective design. This weblog is a case study in teaching object orientation."


Why OO Sucks by Joe Armstrong

Ralph Johnson, Joe Armstrong on the State of OOP (2010)
"He said object oriented languages aren't object oriented. I might think, though I'm not quite sure if I believe this or not, but Erlang might be the only object oriented language because the 3 tenets of object oriented programming are that it's based on message passing, that you have isolation between objects and have polymorphism.

Alan Kay himself wrote this famous thing and said 'The notion of object oriented programming is completely misunderstood. It's not about objects and classes, it's all about messages'. He wrote that and he said that the initial reaction to object oriented programming was to overemphasize the classes and methods and under emphasize the messages and if we talk much more about messages then it would be a lot nicer. The original Smalltalk was always talking about objects and you sent messages to them and they responded by sending messages back."

Thread Thread
 
jwp profile image
JWP

The mass psychosis is in the wording of this article and the author's intent to elicit attention. It has no regard for anyone still using OOP and is simply a lie. Why bash OOP when you could have written an article about FP.

Thread Thread
 
peerreynders profile image
peerreynders • Edited

Why bash OOP when you could have written an article about FP.

You said it yourself "attention". Look how many comments there already are.

It has no regard for anyone still using OOP and is simply a lie.

Lie is perhaps a strong word but it's a rather biased rehash of previously known limitations. Every paradigm has limitations and it's important to be aware of them and know how to deal with them. To some degree it plays on the one language theme—in a "one paradigm" way.

Otherwise just ignore it.

If for whatever reason I was tied to the C# ecosystem right now I'd be paying more attention to Mark Seeman (Code that fits in your Head)

He's a veteran in the OO space and is simply looking for better solutions to real problems.

(And beyond that Scott Wlaschin.)

Thread Thread
 
jwp profile image
JWP

I read Seeman over 25 years ago, he's nothing special. All OOP winds up functional. What? Yes SRP guarantees it. So all your noise shows you are unaware of that.

Thread Thread
 
peerreynders profile image
peerreynders

After 25 years you should have stopped clinging to SRP by now.

It's a place to start ... not dogma.

With statements like that you are just feeding into the author's argument.

Thread Thread
 
polterguy profile image
Thomas Hansen AINIRO.IO

The "point" isn't "to win", the point is to find the best argument ...

Collapse
 
gjorgivarelov profile image
gjorgivarelov • Edited

Just laid down a book I am reading on object-oriented programming in Python. Lol Thomas, which OOP developer hurt you? 😄 Entertaining post though. Exposes how ugly the purists' approach to coding can be.
If your goal is to kill that fly that was bugging you all afternoon long, you won't buy a gun to finish that poor insect off. There's an assortment of problems that OOP can solve more efficiently. Then there are usage scenarios where functional programming is superior. But then you have purists that force their one and only one purest approach to every problem they are assigned to solve.

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

Hehe :D

My problem isn't as much with OOP as it is with "the fanatic believer" yes, as you adequately pinpoint ;)

Collapse
 
chucknorris profile image
Tom

Thank you for the post.

A small comment: Golang is almost as much of an OOP language as Java or C++. It doesn't force you to use OOP but it has objects (a function with receivers is an object method), and I have seen it used in a very standard OOP way: everything is an object, design patterns, SOLID, and so on. Sure, it doesn't have inheritance, but it's still just as possible to write OOP.

Similarly, it's possible to write non-OOP Java. I guess the correct way to classify these languages is "OOP-capable", and Goland definitely fits the bill.

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

Thx for the details. I haven't really done that much GoLang development, so I wouldn't really know. But thx :)

Collapse
 
chasm profile image
Charles F. Munat

Yo, Thomas. Why argue with the psychotics? The only people who truly love OOP are the people who have only ever used OOP. I've known many people who have switched from FP to OOP. I've never known one to go the other way.

This comment stream is a pointless waste of time. If you're going to publish controversial (but obvious) truths like this, just turn the damn comments off. You will never convince the psychotic of their psychoses. Those who aren't actually psychotic about it will maybe try FP and few who give it a real try will ever go back. Slowly, but surely, OOP is losing steam. The word is out.

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

Thx mate, and you are correct ...

Collapse
 
rippletank profile image
Rippletank

Isn't it all much more fluid than all that, practically speaking? Isn't mixing and matching more common?

Just thinking of C#:

Here's the parallel fetch (using the excellent Flurl library for http):

async Task<T[]> GetTwo<T>() => await Task.WhenAll(new[]
            {
                "http:/somewhere.com/api1".GetJsonAsync<T>(),
                "http:/somewhere.com/api2".GetJsonAsync<T>()
            });
Enter fullscreen mode Exit fullscreen mode

Not quite as brief but still readable and flexible.

And the hashing question wouldn't need a class, first instinct would be an extension method in a static class in a shareable string helper:

        public static string ToSpecialHash(this string s)
        {
            //Hash algo here
            return s;
        }
Enter fullscreen mode Exit fullscreen mode

Then just used like this:

        "Hello".ToSpecialHash()
Enter fullscreen mode Exit fullscreen mode

In fact, linq and other "fluent" libraries, are very common. And popular I think. They feel expressive and satisfying to use. But also, sit happily along side OOP, classes, interfaces, inheritence, dependency injection etc etc which also feel powerful and comfortable to use when done well.

The graphics reference is interesting, there it's about speed in parallel. You have to think different anyway. For example, if you have a reasonably heavy calculation, in desktop or embedded, you might implement a look up table, in shader code, its quicker to calculate it each time. And you never want to do an if branch.
And DOTS (with the Burst compiler in unity, at least) give you incredibly fast function calls but all setup and organised inside game objects.

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

Beautiful flurl code - I wasn't aware of that it could do that.

Collapse
 
zakwillis profile image
zakwillis

First caveat. I took a look at hyperlambda - it looks interesting.

It isn't about whether OOP is right or not. Instead it is about getting to the bottom of what the job needing to be done is. I read Plato's Cave way back, and without rereading it, believe it pretty much maps out OOP over 2000 years ago. This doesn't mean it makes OOP valid today, but modelling out instances or classes topologically makes some sense. Whether it is optimal or could be misused is a different question altogether.

In no way, is this stating that OOP is the right way to go - I don't do it, but if people do a bit of inheritance, it can make sense.

Where you mention thousands of classes - well, it does make sense to break things down to smaller chunks, logical units of work. A lot of the code is boilerplate and offers granularity. Would a project with thousands of classes make sense? Doubtful.

Your point on encapsulation - well, that is more of an expression of intent? How much should one open up the functionality? Aren't functional calls a product of encapsulation? Hyperlambda appears to be a declarative language which has to be a product of encapsulation?

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

The problem with OO encapsulation is that it becomes much more difficult to create your code because you start out with something that's intrinsically a verb, and you then have to apply a subject to it. Before you do, you need to group your verbs together in logical entities belonging to each other to create a subject that makes sense. In an FP everything becomes simpler because you can just do.

do(data);
Enter fullscreen mode Exit fullscreen mode

No grouping of similar verbs, which always is bound to fail BTW because of our incapacity to predict future change. FP has fever "opportunities" for over engineering, because it follows the natural path of our thinking. It's intrinsically "simpler" in structure.

I took a look at hyperlambda - it looks interesting

Thank you :)

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

Somebody here asked me about Hyperlambda use cases a month ago, but this discussion is way too long to try to find a specific comment in it, so I'll just provide my example use case here and hope the person sees it :)

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

when someone says "OOP" you can generally assume a red flag of them using classes

Few realise this, but it's perfectly possible to use C# as a partial functional programming language. Yes indeed, my rant was more about the style of programming people use, than languages themselves. Every time somebody spells out SOLID for instance, I swear a fairy dies unless you rapidly clap your hands or something ... :/

As an interesting peculiarity, I wrote Hyperlambda (a 100% functional programming language) in C# (an OO language), using most best practices from OO, and even providing dynamic bindings towards C# classes and types ...

Collapse
 
oducille profile image
Oliver O. duCille • Edited

I still don’t get the advantage of MVVM! Can’t just buy into the mass psychosis. Is it just me? And vb.net? I’d rather use vb6 than this wolf in sheep’s clothing, VB.NET! Still reeling from the m$ betrayal of the vb6 community, I guess. They could have spent that energy on delivering true polymorphism to vb6 along with the other fixes we all were clamoring for as well as included the vb6 runtime MSVBVM60.DLL calls into what’s now the CLR and solved DLL hell…but no killing a wildly successful language while shipping development overseas and forcing everybody onto a new platform was more profitable!

How many knowledge workers jobs were sent overseas. How many of those workers had new homes and most likely they also qualified for some of those crazy mortgages of the early 2000’s with huge balloon payments? How many couldn’t refinance because those jobs were shipped overseas?

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

Somebody here asked me for a use case, so I created an open source use case you can study and look at that demonstrates my point here ...

The above will be our primary support ticketing system at Aista

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

With a (good) functional programming language it’s not possible, not even in theory, to end up in “monolithic hell”. Monoliths is a (mostly) pure OO problem …

As to your C problems, I feel sorry for you. C has nothing to do with functional programming though …

Collapse
 
phantas0s profile image
Matthieu Cneude

In short:

  1. You don't prove anything in there. You just insert statement and label them as proofs.
  2. There are different styles of OOP. Alan Kay's OOP is very different from Java's OOP, which is different from R actor model (arguably a form of OOP).
  3. Polymorphism has nothing to do with OOP or functional programming, it's related to type systems.
  4. OOP and functional programming are orthogonal.

I agree on something though: there is a lot of misinformation out there.

Collapse
 
fyodorio profile image
Fyodor

LISP
GoLang (yup, no OO here)

Wait, doesn’t Go use structs which combine behavior and data?

Totally agree with the opinion btw 👍

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

Yes, but as I've understood it (I'm no GoLang expert), it's about as far way from OO you can come today without being "bullied our of the room" ... ;)

Speaking up against OO is difficult today unfortunately - It's kind of like speaking up against the Pope back in the 1500s ... :/

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

People see objects, realise they're useful, and think they have to build their entire programming paradigm around them. The problem is that objects are a good abstraction for certain problems, but terrible abstractions for others.

Say you have a mutable string as an object and want to write a hashing function for it. Some languages let you monkey-patch the string class. That's an atrocious idea. More likely, the OO programmer will write a string hasher class. They may even find some state to shove into the instance, so it seems more like a proper object.

But the thing is: hashing a string is a function. It's not an object, it doesn't have state, and it certainly doesn't need inheritance.

Once you learn that difference, objects can be really useful. They are very good at one specific thing: Abstracting mutable state. Beyond that, whether you define class.method() or procedure(type) is little more than syntax.

Collapse
 
jwp profile image
JWP

The real loss of reality was that for 20+ years Javascript was the only language a browser supported. Thank God those days are over.

Collapse
 
devonadam profile image
devonadam

"For the record, if you want to work in a sane programming language, there exists dozens of nice languages out there"

but this is cop-out.
i think the point is you have to pick one

Collapse
 
jinek profile image
Evgeny Gorbovoy

Single responsibility is nothing to do with oop.
SOLID is against OOP.
Could anyone give an example of classical vehicle/car/helicopter example to be done shorter without OOP anyhow?

Collapse
 
ltsochevdev profile image
Sk1ppeR • Edited

PHP nowadays, for all it flaws, supports both paradigms (functional and OOP) and at its core it leans more toward the functional side (e.g. strings aren't objects, doing string work requires you to call functions, no "hello world"->capitalize() etc...) And I must say. When browsing through open source repos and projects, whenever something is functional it's a clusterfuck. Most often in large functional projects even basic things like documentation are a clusterfuck. It's far easier in OOP to go through unknown code. As long as you know your design patterns all you need to do is "Object->" and you get all the available methods inside your IDE. With functional structure ... I don't know where to begin, lol. Also it's very nice that private/protected methods - I don't even care about them in the slightest unless I'm extending a class. Although, extending a class of a library is generally frowned upon. Rather use composition and rely on public methods. I am coding professionally for a little over 12 years across various languages. I have yet to see a large functional project that's easy to work on. All the assumptions you've made that "less code - better" is kind of a shitshow. There's a term - cyclomatic complexity and OOP is guilty of falling into the pit but it's up to the programmer. There's a reason Laravel is the most popular framework in PHP-land. It's not because it's better than Symfony. It abstracts everything away and reduces everything to one-liners for the most part. Close to 0 cyclomatic complexity. It's a breeze working with that thing. And it's OOP. Also while we're at it, fuck hungarian notation.

 
jwp profile image
JWP

He's acting as if there's no IL generation. He doesn't get that we can do all of the example in one line of code. Nobody cares what IL generates. We're using 5 core GHZ processors now.

Thread Thread
 
peerreynders profile image
peerreynders

That's not the only angle.

Data-Oriented Design (Or Why You Might Be Shooting Yourself in The Foot With OOP) (2009).

Why?

Data-Oriented Design: What's wrong? — Mapping the problem:
"Object-oriented development is good at providing a human oriented representation of the problem in the source code but bad at providing a machine representation of the solution. It is bad at providing a framework for creating an optimal solution, …"

Which ultimately lead to the development of the Entities, Components, Systems (ECS) architecture.

"The most amazing achievement of the computer software industry is its continuing cancellation of the steady and staggering gains made by the computer hardware industry."
— Henry Petroski

The processor-memory performance gap (especially on commodity hardware) forced certain segments of the video games industry to abandon OOP.

This lead Unity to develop their "Data-Oriented Technology Stack" (DOTS) which introduced a C# dialect—"High Performance C#" (HPC#).

Thread Thread
 
polterguy profile image
Thomas Hansen AINIRO.IO

Brilliant walk through, thx mate :)

 
t4rzsan profile image
Jakob Christensen

LINQ is great and it is in fact a functional paradigm. The same goes for the fairly new C# record types and switch statements. C# has been adding more and more functional capabilities.

LINQ is a great example of what @polterguy means when he says that programming is about input -> verb -> output.

The LINQ function SelectMany is usually called flatMap or collect in the FP world and it is a part of the defition of monads. So collections in C# can behave in a "monad-ish" way in C# with the addition of LINQ.

Thread Thread
 
polterguy profile image
Thomas Hansen AINIRO.IO

And we didn't even mention Action and Func yet ... ;)

Collapse
 
anuragvohraec profile image
Anurag Vohra • Edited

Anti-OOPs ranters === OOPs noob

You have argued exactly 4 points ranting (as will be called without examples), to declare OOPs suffereing from psychosis.

I will disect your first point, as rest are equally bad without examples:

Implementing encapsulation in OOP results in unnecessary complexity and virtually impossible to understand code

This acclaim is as extraordinary as : I stabbed myself with a rubber duck!, rubber ducks are created to be soft toys, how you ended up stabbing yourself is bit difficult to comprehend.

Encapsulation by the very definition means to hide complexity and wrap such complex code into simpler interface. How you ended up using Encapsulation,an otherwise conceptual medicine for complex code, to create complex and virtually impossible to understand code ?

Collapse
 
mich160 profile image
Michał

If OOP was a solution to anything really, we wouldn't need design patterns, clean architecture, or SOLID design principles. OOP itself would be enough for us. The fact that OOP need crutches to stand upright, is by itself enough proof for us.

Nobody told that OOP is solution to everything by itself. It is merely a tool for encapsulating complexity. And yet it is often misunderstood and misused. Please do not build a strawman.

Collapse
 
pauljlucas profile image
Paul J. Lucas

Your entire post needs one big [citation needed]. That which is asserted without evidence can be dismissed without evidence.

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

The evidence is in our code. Open your IDE and look at the last OOP project you delivered, and ask yourself; "How would this look like in a functional programming language?"

Collapse
 
spronkey profile image
Keith Humm

Probably pretty much the same, but with far less organisation, and far less friendly to newer developers?

OOP and FP aren't mutually exclusive. SOLID principles don't automatically result in code explosions.

Thread Thread
 
polterguy profile image
Thomas Hansen AINIRO.IO

OOP and FP aren't mutually exclusive

This is a good point, and when I code in C#, I typically choose the functional constructs much more than the OO constructs ...

... yes, C# has a lot of functional constructs ... ;)

Collapse
 
pauljlucas profile image
Paul J. Lucas

Anecdotes are not evidence.

Collapse
 
dragzter profile image
Vladimir M. • Edited

I appreciate your sentiment and I believe you make some compelling points, however, you are not presenting any concrete evidence. You are making the claim that OOP is not the answer, ok, fine, why? Just saying that it's convoluted is not enough because anyone is capable of creating terrible unreadable code. It is possible to write terrible OOP code for many reasons. Furthermore you say functional programming is better, I tend to agree for the most part. Why? It just seems like you dislike OOP and want to see it removed.

I agree that any programming paradigm can be poorly executed regardless of its merit. Poor application of principle can lead to faulty and subpar code.

I also believe OOP has it's place as does FP.

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

The proof is in the code. Look at any "brilliantly architected OO solution, with all the relevant design patterns, 'SOLID' as a rock". But thank you.

Collapse
 
siy profile image
Sergiy Yevtushenko

By the way: FP has its own design patterns. They are just different than OO ones. Functors, monads, lenses, etc. are nothing else than design patterns.

Collapse
 
dmitryefimenko profile image
Dmitry A. Efimenko

Looks like a lot of hand-waving. Show me proof with some practical examples!

Collapse
 
lewiscowles1986 profile image
Lewis Cowles

Oh man... Mass psychosis

Hyperbolic much?

Thank you for sharing, but please work on language.