HN Theater @HNTheaterMonth

The best talks and videos of Hacker News.

Hacker News Comments on
Object-Oriented Programming is Bad

Brian Will · Youtube · 265 HN points · 36 HN comments
HN Theater has aggregated all Hacker News stories and comments that mention Brian Will's video "Object-Oriented Programming is Bad".
Youtube Summary
An explanation of why you should favor procedural programming over Object-Oriented Programming (OOP).
HN Theater Rankings

Hacker News Stories and Comments

All the comments and stories posted to Hacker News that reference this video.
I find an uncanny correspondence between the recommendation given here, following as it does from an interpretation of the Agile manifesto, and Brian Will's procedural programming recommendation contra OOP in his classic 'Object-Oriented Programming is Bad'[1]

[0]https://www.youtube.com/watch?v=QM1iUe6IofM

I'm reminded of the "Object oriented programming is bad" series: https://youtu.be/QM1iUe6IofM
cloogshicer
It's really great, highly recommend it!
codemonkey-zeta
For anyone unfamiliar, I recommend the whole series, but it also culminates in the presenter rewriting an entire nontrivial OOP program into a procedural one and saving whopping amounts of code/complexity. The big example helps to show this isn't just abstract rambling against OOP.

https://m.youtube.com/watch?v=V6VP-2aIcSc

magicalhippo
To me, his title is somewhat misleading though. It seems he's against the extreme "everything is an object" version of OOP. I think taking things to the extreme is almost always a bad thing. Sometimes goto is a good solution.

I do agree with most of his points though, which just so happens to be closely aligned with how I've ended up programming. I like to use interfaces, so my objects hierarchies are very shallow and use a lot of delegation, overriding few if any methods.

I also write a lot of free-standing functions, some long, when I feel that's best. I also mix in a fair bit of functional-like programming, especially when massaging data.

codemonkey-zeta
> he's against the extreme "everything is an object" version of OOP

I totally agree with you. I think he focuses on this style because it's generally what's taught in Universities, and he also has tons of tutorials geared towards students. So he's exposing his audience to the idea that some OOP principles are good, but overly adhering to the paradigm (in the way that would get you a 100% grade in an OOP class in college) is actually a bad way to program in general.

magicalhippo
That's a fair point, and as I mentioned I do agree with his conclusion.

Being self-taught, I was already a proficient programmer in Delphi and C++ by the time I went to University. So to me OOP has always been "OOP when you need it".

Though now that you mention it, even by the time I started University I had a profound dislike for Java's "OO all the things" approach. It has not subsided...

May 23, 2022 · 1 points, 0 comments · submitted by tsujp
May 01, 2022 · 15 points, 6 comments · submitted by robomartin
karmakaze
It doesn't seem to be a very historically accurate or cover modern examples where OOP works well. The original OOP was Simula 67 used for simulation that doesn't use the definition of OOP in the video. I have no idea where that one comes from.

I'd say maybe 50% of application code I see (not write) are web UI/clients. Something like React with OOP components work very well. Same goes for mobile or UI's in general. The argument would be more persuasive if it used a more common definition of OOP and concrete examples of both good and bad applications to show which kinds of cases fit and which don't.

bluenose69
The speaker raises key points in a remarkably clear and engaging way. I end up watching many lectures at 1.5 or 2.0 speed, because they so often have low information density. Not so, in this case. If you're interested in programming, you owe it to yourself to spend 3/4 hour on this. You may also find yourself pausing the video from time to time, to sit back and appreciate the elegance of the exposition. A lot of nails are hit precisely on the head in this lecture.
kgbcia
i like oop for namespaces. if only c had them. I recently went back to php after JavaScript. Js has a string object, so if you want any string function you know where to look. Php has a bunch of functions with str prefixes which could lead to namespace collision.

I like oop because of custom types. Awhile back I had to create a vector class in python. Since Python support type hints, vscode automatically warned me if I pass the wrong object.

JaceLightning
Speaker seems like he has never worked on a large project nor understands OOP. He mentions Single responsibility principal but then seems to understand its usage or effectiveness, saying that your logic is scattered all over the code base. It's not if you do OOP right.
robomartin
I could not agree more with the points being made in this presentation. It pains me to see just how ingrained OO has become --due to it being taught in school almost as the only way to program.

I have seen the results of this in open source libraries with insanely complex object structures that can often be reduced down to very few lines of procedural code. The most extreme case of this I have seen was a serial communications library for Arduino. I showed this to my son, who, at the time, was in the middle of his CS degree journey. After understanding what the library did, I rewrote it in four lines of code.

The other aspect of this issue is performance. Being that quite a bit of my work for over 30 years has been focused around real-time hardware, embedded systems and robotics, performance has always been at the top of my list. OO can be absolutely horrific in this regard.

I remember writing an iOS application back in iPhone 3 days, which meant Objective-C. I used all of the native object data types and kept it to Objective-C. The performance was absolutely horrible and unusable. The application was based around a genetic solver. It needed to run thousands of generations fast, as fast as the user clicked on a button. Well, that wasn't happening at all. I re-coded the entire thing procedurally and got rid of every single object data type and calls to encapsulated object functionality. The genetic solver ran nearly 400 times faster with a marked reduction in resources.

Of course, my journey through programming has been very different from what students experience today. I started with machine language, then moved to assembler, C, Forth, LISP, APL and beyond. C++ came into my life after these languages had been part of my work for years. Exploding a codebase into nearly incomprehensible hierarchies of inheritance and polymorphism-laden classes made little sense to me at the time. Yet, I dutifully jumped on the bandwagon and adopted the cult at the time.

It didn't take long for me to privately think "this is bullshit" and, eventually, express the opinion in a more public form.

I can't remember the last time procedural programming has prevented a project to be completed on time and with the requisite functionality. This spans consumer to industrial and aerospace projects. I will use OO when absolutely necessary and justified. If you are using Django and have to create class-based views, well, enjoy. On embedded systems? Not necessarily.

I know this is likely to be controversial. When you have a whole generation of people for whom the first thing they type on a fresh source file after some imports is "class", well, they might just not be equipped to understand they don't have to. That's just reality.

None
None
akhmatova
This is silly. Yes, the cult of OO (and overuse of OO) is bad. But at the end of the day it helps people get stuff done. Even if it may be "flawed" in concept. So in that category it's just like ... Unix, TCP/IP, or ... ASCII, or ... just about any large-scale programming language you can think of.

Just another variant in the "Why the 'else' statement is bad" genre, this video.

That's fair - I'm not against abstraction in general. I agree that we wouldn't be able to handle the essential complexity of software without it.

I'm just saying that each abstraction also has a cost, and makes understanding the whole thing more difficult. Abstraction is, in my understanding, a necessary but costly tool.

A lot of my thoughts are summarized well by Brian Will in this video:

https://youtu.be/QM1iUe6IofM

Mar 13, 2022 · DeathArrow on .NET Myths Dispelled
I think this is a valid critique. But then, most of the development (C aside) has been a victim to OOP.

I have begun to think that OOP creates more problems than it solves. Added complexity and performance loss being the biggest. It's insane if you peek into a big projects where many developers came and went and each of them read an article about what it seemed an interesting design pattern and tried to implement them.

You can have some kind of procedural programming if you use classes just to store data and use static methods. But the frameworks are OOP and there is no way around that unless you write your own frameworks.

I am a big fan of Mike Acton's Data Oriented Architecture speeches, but I didn't find a way to implement something similar in C#.

For those interested in something better than OOP, here's a few links:

https://youtu.be/rX0ItVEVjHc

https://youtu.be/QM1iUe6IofM

https://youtu.be/pgoetgxecw8

Mar 13, 2022 · zamalek on .NET Myths Dispelled
Here's a really popular video that touches on many of the contentions: https://youtu.be/QM1iUe6IofM

My personal tipping point was the realization that OOP forces you to first figure out how you solution maps to OOP, before figuring out (or iterating on) how it maps to code. It creates nothing more than accidental complexity: https://emangini.com/2021/07/05-accidental-complexity/

masterofmisc
Its hard to know what people mean when they say OOP anymore.

Im just watching now and he advocating for your code to be "procedural" rather than "object-oriented".

And when he says "procedural", he doesnt specificlly mean "functional programming". So, when he says "imperative procedural programming" he means that you have no explicit association between your datatypes and your functions/behavours.

And just to be clear they are not saying its a problem to see an object in your code!! Its the traditional OOO (Object Oriented Objects) that have state and method calls/behaviours.

And thats pretty much the way I code in C#. My data objects are just that. Simple data! And I have other objects that are a collection of functions that take in POD (Plain Old Data Types) objects or return PODs.

He goes on to explain how encapsulation is the problem. Thats where you have an object that holds state/information hidden behind a public interface as well as methods to mutate the state. And when you call that method, it might call through to many other methods on other classes. And if thats the case, it means the object your calling the method on has references to those other classes it depends on. Which means those dependencies/objects must be provided to it via construction.

I have not watched the whole video but I tend to agree with what he is advocating.

Mar 07, 2022 · 3 points, 0 comments · submitted by kjeetgill
Oh I'm looking at the development side, being able to iterate quickly and having full visibility of the code. This fits in with stuff like aspect-oriented-programming (AOP) so that things like execution traces can be generated at runtime without modifying code.

I mostly work with the shell and scripting languages. I'm racing as fast as I can all day to get anything at all to work, then building on that to get to a solution. Most of the time, I can't really edit the code I'm working with and still maintain velocity, so can't do any kind of manual type annotation.

Also I question if there is really any merit to hiding the type of a variable at runtime. It feels like a power trip by the language, a form of security theater. I also view the "private" and "final" keywords with similar skepticism. If I can call typeof on an element in my own struct/class, then I get frustrated when I can't do that with anonymous data from a framework or in the REPL. It also frustrates me when I can't access the call stack or get information about the calling function. If there's a way to do it in C++ (no matter how ugly), then I must be able to do it in whatever language I'm using or my psyche views it as stifling and I lose motivation.

I guess I find the obsession with types today to be a form of pedantry. So much concern for only accepting a narrow range of shapes, but then holding that info close to the chest. It should be the opposite.

That's also the reason why I've gotten away from object-oriented (OO) programming. I've found that functional programming (FP) on JSON types (number, string, etc), and doing declarative programming in a data-driven way, usually runs circles around the boilerplate/interface yak shaving of OO.

Object-Oriented Programming is Bad:

https://www.youtube.com/watch?v=QM1iUe6IofM

Simple Made Easy:

https://www.youtube.com/watch?v=LKtk3HCgTa8

Dec 15, 2021 · 4 points, 0 comments · submitted by agomez314
Engineering within the wrong paradigm can kill your product.

I see far more problems on a day-to-day basis with patterns and anti-patterns taken too far. For example, I never use the factory pattern, because it leads one down the Java road where everything ends up an object with mutable state. Which isn't scalable over some metric (like a million lines of code) because a human brain can't trace execution, even with a debugger. A far better pattern generally is to take a functional approach of accepting data, swizzling it, and returning the resulting data without mutability or side effects.

Another really bad pattern is when execution suspends and resumes somewhere else (goto hell). Any project which uses queuing, eventual consistency, promises, nonblocking streams, even basic notifications or things as complex as monads will encounter this nondeterminism and inability to statically analyze code. Note that pretty much all web development suffers from some aspect of this due to its async and multi-signaling nature.

So what I do now, which I don't see much these days, is solve problems abstractly in a spreadsheet (pure functional programming), in the shell (the Actor model) or as a flowchart (declarative and data-driven design), and then translate that to whatever crappy language/framework I have to use for the project. I find that today, roughly 90% of developer effort goes to discovery, refactoring and testing of ill-conceived code. Only 10% is "actual work" and that's probably a stretch.

Which is incredibly heartbreaking for me to see, since I grew up on software like HyperCard, FileMaker and Microsoft Access which solved much of this in the 1980s and 90s in a no-code fashion. One of the very first "languages" I used was a visual programming environment called Visual Interactive Programming (VIP) for the Macintosh by Mainstay, which unfortunately today I can find almost nothing about, to show what an impact it had on computer science hah: https://duckduckgo.com/?q=Visual+Interactive+Programming+VIP...

With mainstream languages and frameworks like Node.js and React, and their predecessors like Ruby on Rails and Angular, I just keep thinking to myself "never have I seen so much code do so little". It's all overengineered man!

Some better alternatives to the status quo:

Simple Made Easy: https://www.youtube.com/watch?v=LKtk3HCgTa8

Object-Oriented Programming is Bad: https://www.youtube.com/watch?v=QM1iUe6IofM

I've had problems with the ideas in Clean Code for a while, but I couldn't really effectively communicate them, until I watched this video by Brian Will. I think it is excellent: https://www.youtube.com/watch?v=QM1iUe6IofM
Somewhat relatedly (covers some very similar concerns and IIRC even references "Clean Code"), Brian Wills has a few good videos

https://www.youtube.com/watch?v=QM1iUe6IofM

https://www.youtube.com/watch?v=IRTfhkiAqPw

I highly recommend "Object Oriented Programming is Bad" and "Object Oriented Programming is Embarrassing" on Youtube.

https://youtu.be/QM1iUe6IofM

https://youtu.be/IRTfhkiAqPw

This reminds me of Brian Will's "Object-orientation is Bad" where he makes the case that most decoupling tends to be more confusing than long-form code that's got sufficient comments.

https://youtu.be/QM1iUe6IofM?t=2235

ZephyrBlu
I hate unnecessary functions with a passion and it's refreshing to hear his opinion.

Sometimes a big, fat block of code is just easier to understand.

anotherforsure
If you have a well documented system, OWNED by a software architect, then breaking it down is better.

If you don't have that, at least big fat blocks of code are self documenting...

wsc981
> Sometimes a big, fat block of code is just easier to understand.

John Carmack made once the same comment: http://number-none.com/blow/blog/programming/2014/09/26/carm...

UK-Al05
I haven't read that in awhile. But the argument was around optimisation rather how easy it is to understand.
ratww
Not really, Carmack explicitly states that this is not a performance optimisation in the article:

> In no way, shape, or form am I making a case that avoiding function calls alone directly helps performance.

Rather, he argues that (among other things) this is a way to make current bugs more visible and to avoid future bugs by disallowing calling functions that should be inlined.

wsc981
The way I read the article, I believe his main point was to make reasoning about state easier, even at a small cost to performance, making code easier to test and debug.
laegooose
Very insightful. Can I read more John Carmack's letters somewhere?
wsc981
Took me a while to find something useful, but here you are:

https://fabiensanglard.net/fd_proxy/doom3/pdfs/

laegooose
Wow that's a lot of interviews and letters. Cheers
tarruda
> I don’t think that purely functional programming writ large is a pragmatic development plan, because it makes for very obscure code

As a functional programming enthusiast, I agree with this.

Recently I worked on rewriting a relatively large backbone web application in React/Redux (For those that don't know, Redux is a framework for writing JS in a more functional style).

While moving all app logic to functional style makes it safer and easily testable, it is definitely not friendly to most programmers that maintain it. We've had lots of bugs caused by new people coming in, not understanding the functional style and making bad changes such:

- Doing side effects from functions that are assumed to be pure.

- Writing a lot of logic into functions that are directly doing side effects, instead of refactoring the decision making into reducers.

While I still love mostly pure functional code, I would only recommend it for smaller projects, where one or few developers with strong grasp of the style would strictly review every new PR to ensure new people don't mess up.

marcosdumay
> Doing side effects from functions that are assumed to be pure.

That completely goes away as soon as your language has purity declared at the type system.

It's just not available for Javascript development, like most nice FP features.

nendroid
That's because JS is not a functional language. You are enforcing a functional style by discipline. Additionally a huge portion of benefits of the functional style are lost on untyped languages. If you're not using typescript you're dealing with a lot of unnecessary bugs.

If you guys moved to a fully functional paradigm where the language enforces the functional style you will see greater benefits.

Unfortunately for the front end the ecosystem for functional languages outside of TS/JS is not that great. But an easy one to try out to actually see the benefits I recommend writing a little app with ELM. With something like ELM, the functional style is enforced by the compiler. You will see that 90% of the bugs you typically deal with in JS/TS will disappear. One type of bug that will disappear is runtime errors. Runtime errors are not possible in ELM.

I find a lot of JS programmers haven't fully grokked the functional style. Example: You'll find JS programmers who talk about how much they like functional programming but don't understand why for loops don't exist in functional programming.

ratww
You're not wrong, but I don't really think this is the fault of FP.

I had the exact same experience with people not understanding new paradigms with Procedural (programmers experienced with Assembly using GOTO for everything), OOP (programmers used to procedural using only static methods), MVC (by putting everything in the controllers and ignoring views/modules/helpers), MVVM (by modifying state by themselves instead of using the MVVM mechanism).

All those things were always "obscure" for newcomers since it was different from what they learned in college, but after a while they became second nature.

I think the answer is not to avoid those paradigms because they're hard, but rather to teach people how to work with them. It's expensive but it's only way forward IMO.

xorcist
Thank you for this.

It has been a strongly held opinion of mine for a very long time, but I haven't been able to state it as eloquently as that.

zytek
I love his series. Eye opener for beginner coders.
ratww
Agreed. IMO it's an eye opener for experienced coders too.
rvense
I think that

    fn x() {
        doStuff();
        moreStuff();
        forgotSomething();
    }
is pretty bad code, but that's probably because I consider procedures with no arguments and no return value a sign that something is poorly factored. However,

    fn x(y) {
       foo = doStuff(y);
       bar = moreStuff(foo);
       if (isSomething(bar)) {
           return theRest(bar)
       } else {
           return theBest(bar);
       }
    }
can be a good way to separate the why from the how and clearly communicate what's going on, especially with conditionals in the mix.

It's important, however, that these helper functions are not haphazardly strewn around the code base and accessible to things that don't need them. Depending on the language/context, I'd reach for nested function definitions or public/private keywords (or a combination), because definitely, it can be very hard to approach a big file with a bunch of (often poorly-named) functions that are defined at the same hierarchical level but not meant to be used at the same level.

peterwwillis
The former example was much easier for me to understand than the latter, even if it wasn't factored well. But I'm assuming that the functions aren't mucking about with global state or something equally distasteful.
shock
> But I'm assuming that the functions aren't mucking about with global state or something equally distasteful.

There's not much else for them to do, since they don't take arguments, but to muck about with global state and/or have side effects.

skinkestek
> But I'm assuming that the functions aren't mucking about with global state or something equally distasteful.

It seems fairly obvious to me that either the former example is waaaay simpler or it is doing something really distasteful.

peterwwillis
Some designs don't require your own code to pass around state between functions, because each function can handle state in its own way without dependence on other functions. I've written a lot of such simple scripts where I just need to execute a series of tasks that aren't necessarily related to one another, but do follow each other.
rvense
Well, if we assume that both are doing the same work, then the explicitly named variables y, foo, and bar of my second example would, in the first example, have to be global variables, or at least things that are defined in the scope of the definition/call of x.

Given that, I have to say that I, err, and I'm sorry if this sounds a little arrogant, but I don't really believe you when you say that it's easier to understand. It might be easier on the eyes, sure, but to really understand how the first one works, you'd have to look into all the defined helper functions, and see which outer-scope variables they touch (global/module/class scope), and also, probably, have some knowledge of where x is called. In a style closer to the second example, there are less outside dependencies.

Of course, this is all very abstract. I'm not saying there aren't cases where a few variables in global (or class) scope that get mutated by bare functions can't work at all, but as a rule I don't consider it a good style.

peterwwillis
I don't really fully understand how the kernel scheduler works, but I know in general how it works, and so I can write software using it. In this sense, a simple implicit abstraction is easier for me to understand than one where I'm peeking under the covers, so to speak.

Even just seeing a few variables or objects passed around, I still don't know exactly what it's doing, or hiding. I can more quickly understand the high level idea with the former example without the details potentially confusing me.

rvense
I see what you mean.

I think it depends on the type of code and how you interact with it. A library that requires its consumer to keep track of a bunch of data and pass it in and out at the right times when it could just as well handle internally is not a very good library. But if we say that all the code the above example is from an application, where a normal change might involve touching all of the mentioned functions, making it explicit where some variable is used.

toomanybeersies
Haven't you just described functional vs procedural programming?
valenterry
It's not explicitly expressed (the functions could still execute sideeffects and e.g. mutate things), but yes, that is pretty much the style that pure functional programming enforces!.
dathinab
No he described implicit arguments and mutation vs. explicit arguments and mutation.

It's independent of OOP vs. functional, through it's easier to have implicit arguments and mutation in OOP so you see it more often there, especially if people somehow ended up believing that programming OOP means you need to create a class for everything and make all states a object member instead of e.g. a variable in the stack.

rvense
Yes! I often see code that where a method sets an instance variable, then calls another method that does some work based on that instance variable, which is then not used until the next time that first caller is used. The instance variable is redundant, and the control flow is obfuscated. I think the principle is just to only expose something when you really have to (harhar), and that the 70's suspicion of unstructured use of global scope should be equally directed to class scope.
amw-zero
That's called temporal coupling, where some code only works if some previous code set some variable earlier in time. And it's a sign that you're building an implicit state machine.
Oct 06, 2020 · 2 points, 0 comments · submitted by vinni2
Oct 05, 2020 · 5 points, 0 comments · submitted by okasaki
At the risk of putting readers off by the title, there's a video essay on YouTube called "Object-Oriented Programming is Bad"[1]. It's both thoughtful and thought-provoking, although I don't agree with the conclusion. Steve Naroff (from Stepstone/NeXT/Apple) did a recent-ish set of interviews with the Computer History Museum[2][3] and referenced that video a bit (and extemporized about objects in small parts throughout). Side note: Naroff and Brad Cox are set to present a paper on Objective-C at this year's HOPL[4]. I wish it were as readily available as Allen Wirfs-Brock's JS paper for the same conference[5][6].

1. https://www.youtube.com/watch?v=QM1iUe6IofM

2. https://www.youtube.com/watch?v=ljx0Zh7eidE

3. https://www.youtube.com/watch?v=vrRCY6vwvbU

4. https://hopl4.sigplan.org/track/hopl-4-papers#List-of-Accept...

5. http://www.wirfs-brock.com/allen/posts/866

6. https://zenodo.org/record/3707008#.XtoRR-TEklQ

foobar_
Every time you call a method you are breaking encapsulation because you can no longer change the name of the method, it is exposing the internals. Thats why Message Passing has more guarantees with encapsulation.

Abstraction is overdone. Sometimes the simplest implementation is a function. Not a class.

Inheritance is a failed idea of code reuse because it leaves the code brittle.

You can develop GUI apps without OOP - Tcl / tk and some game programming guis are done that way. All that you need are callbacks essentially.

Polymorphism is essentially overloaded functions and you don't need OOP to support that.

pjmlp
Polymorphism is OOP, not every approach to OOP is the same kind of nail.

Classes as concept, are nothing more than extensible modules, and in that regard C and Assembly are pretty much the only mainstream languages that eschew such abstractions.

You can also develop GUIs in Assembly, and I don't miss doing that.

Interesting that you mention Tcl/Tk, given the OOP extensions that were all the rage when version 8.0 came out.

https://wiki.tcl-lang.org/page/Object+orientation

foobar_
You missed the first point I made. C++ / Java break encapsulation by using methods and pretend they are encapsulated.

Julia implements polymorphism without OOP. Modules are better than classes anyways. The whole Java ecosystem tried so hard to bring modules back as components and failed miserably.

If we are going to talk about all types of interfaces then OpenGL is a clear winner. That last time I checked it uses a procedural interface and vertex buffers directly. Why a procedural interface ? Because OOP is incapable of dealing with any complex data structure other than lists in a performant way.

pjmlp
Modules are classes without inheritance.

C++ and Java don't break anything that a bad designed module won't be doing as well.

OpenGL a clear winner?!? The 3D API that should never haven gotten outside SGI with its global variables and state?

foobar_
That's exactly why modules are better than classes because they don't have inheritance. It allows for simpler solutions. No debates about taxonomies.

OpengGL is faster. Procedural code is always faster. Global variables are infinitely better than pretending problems vanish with singletons and AbstractFactoryMakerProducer. I remember going from C++ to Java, what a joke. C++ is infinitely better than Java because it doesn't suffer from OOP monothinking which is beyond pathetic. It was the first time I realised programmers would repeat marketing slogans without verification.

pjmlp
Modules can still be generic without inheritance, it is a matter of language and implementation.

OpenGL is a garbage API that I repent having spent so many years dealing with its Frankenstein API design.

Fast? Only if you happen to use the magic incantation of data structures and the driver happens to play ball.

There is a reason why all modern 3D APIs are object based, including Vulkan with its handle model.

OOP based C programming is used all over the place in the Linux kernel, in spite of Linus opinions regarding C++.

foobar_
I found OpenGL easy enough as compared to DirectX which is an abomination. Another problem with OOP, it breaks ABI because of name mangling. Had people just stuck to modular programming without inheritance this would have been a non-issue. Namespaces would have become underscores or something.

You can almost backtrack all the horrible decisions in C / C++ and compare it to wirth languages which tried modular programming, bounds checking ....

> Vulkan with its handle model

That sucks. The performance is going to be slow. It's possible they did not go full OOP because of performance.

> OOP based C programming is used all over the place in the Linux kernel

Nope. They implement interfaces / modules using structs. Again, no inheritance and "classes". The most popular example being drivers and filesystem.

pjmlp
OOP doesn't require inheritance, and structs with function pointers are how "classes" get done in C, better brush up your knowledge of OOP, and while you are at it, learn about Vulkan as well.

Also in case you have missed, all proprietary 3D APIs are either OOP or object based.

I wonder where is the OpenGL C implementation that will outperform LibGNMN.

By the way, one of the reasons why OpenCL failed to gain market shared was its focus in C, instead of the nice C++ libraries provided by CUDA.

When Khronos woke up and decided to offer such APIs, it was to late, now we have OpenCL 1.2 renamed as OpenCL 3.0, and SYCL is being re-designed to be backend agnostic.

foobar_
From a quick read, Vulkan doesn't use inheritance. Its using the C module approach. Even the Web DOM doesn't use inheritance. It seem in the real world no one uses imaginary objects and everyone uses structs.
pjmlp
Advised lecture, "Component Based Programming".

Again, OOP is not 100% about inheritance.

It seems some people keep not learning what OOP is all about and relate OOP <===> Java.

foobar_
I think you are finally getting it. Modules ~ Components. Where you and I differ is you think Component = Object. I think the difference is sufficient enough to warrant a complete divorce from the word object.

Linux kernel uses components, not objects.

The ideology of OO is using classes and inheritance to design software. It is an abysmal failure of software engineering, only mediocre managers use OO anymore and pretend visitor pattern is still a thing. All successful OOP projects use components in a disguised form and use a separation between Data (Value Objects, POJOs) and Code (Services). All failed OO projects use classes and take 3 years to deliver even the dumbest of software.

pjmlp
No you are the one not getting it still, components are an area of OOP, usually referred as object based programming.

SELF, BETA and JavaScript don't use classes yet are OOP.

VB originally did not do inheritance and yet it did provide another OOP approach.

Plenty of other languages can be looked upon on SIGPLAN.

Speaking of failed OOP projects, Web DOM, Android, iOS, CUDA, DirectX, LibNMN, LLVM, Metal are indeed such a colossal failure, what were they thinking.

In case you are lacking CS literature I can give you some hints.

foobar_
That fact that you have to go through so many references to define the word object exactly proves my point.

You can just read this wiki ...

https://en.wikipedia.org/wiki/Modular_programming

Modularity is the very fabric of most engineering disciplines. As opposed to that, OO is a holistic "ideology" about using classes and inheritance to design software. I call it an ideology because despite its abysmal failures people still refer to it in positive terms.

Apart from Android not one software from the list uses inheritance and classes. OO has shown a narrow success in GUI.

In C you don't have modules and interfaces, so what you do is define a struct with pointers. Now you can compile any .c file which follows this interface and dynamically load it into the software.

Python / Perl / Javascript / Ruby ... support this. Remember how much code is resused in the packages downloaded when you do pip install ? Thank modules for that. Not OO. Because of duck typing these dynamic languages don't need interfaces but you can find code snippets that implement it with keywords like pass.

In modular coding you get libraries, extensions and plugins. I find it sad not many people use these terms and prefer to honk OO every time.

layoutIfNeeded
Modern OpenGL is also object-based. You select which instance you want to interact with via glBindX.
pjmlp
AZDO is not compulsory and rarely seen live, for example it isn´t supported in ES or WebGL variants.
l_dopa
> Classes as concept, are nothing more than extensible modules

If you're talking about ML-style modules, that really can't be farther from the truth, both in theory and how they're used in practice.

Modules can be used (among many other things) to implement abstract data types, which are conceptually a bit easier to compare to objects[0]. Then you'd have to go into structural vs nominal typing, functors vs generics, etc.

[0]https://www.cs.utexas.edu/users/wcook/papers/OOPvsADT/CookOO...

pjmlp
No, I am speaking about modular programming as abstract CS concept, with those nice math diagrams to describe language semantics.
panic
The HOPL paper is available here: https://dl.acm.org/doi/abs/10.1145/3386332 (the PDF link even works without an institutional login!)
cxr
Thanks a ton! Earlier this week it didn't look like it was available. https://news.ycombinator.com/item?id=23436517

Looks like there's another Smalltalk paper, too:

https://dl.acm.org/doi/abs/10.1145/3386335

I suggest searching google for "problems with object oriented programming". There have been countless discussions, articles and videos.

Examples: https://www.youtube.com/watch?v=QM1iUe6IofM https://medium.com/machine-words/the-rise-and-fall-of-object... https://medium.com/@cscalfani/goodbye-object-oriented-progra...

This isn't about OOP vs. FP.

This is about OOP vs. everything else.

Rust, Go and javascript are three languages that are moving away from the OOP paradigm. None of those three languages are classified as functional.

>Is there some resource you can point to that says in the past when faced with situation X developers tended to use pattern Y, these days that has been superseded with way of doing things Z?

No. A general trend is an anecdotal observation. Still a quick google search yielded: https://blog.cleancoder.com/uncle-bob/images/fpvsoo.jpg

Take a look at the following video:

https://www.youtube.com/watch?v=QM1iUe6IofM

While I don't agree with a lot of it, I think it sums up my opinion really clearly. It's not about DP's but because DP's focus around OOP and the video is a criticism of OOP therefore the arguments apply to DPs.

james_s_tayler
Thanks. I've observed this as a general trend too. I'm starting to become more and more interested in the functional way of thinking.

The image you linked it interesting. I want to dive more in on the how/specifics. I don't necessarily buy the argument it's trying to make that "just make a function and you no longer have a need for factory pattern". You're trying to accomplish something fairly specific with that. Functions compose, I could see how there are properties they have that can be leveraged to achieve the same goal, but I'm guessing the functions you write or the way you write functions to achieve each of those specific aims likely differ in subtle yet important ways. I'm very interested in those details.

crimsonalucard
>I don't necessarily buy the argument it's trying to make that "just make a function and you no longer have a need for factory pattern".

The same pattern is achievable with functions but the implementation is so trivial in FP that it doesn't even need a name:

Just have a function return another function. That's a function factory.

Same thing with dependency injection:

Just have a function take another function as a parameter.

Outside of this I wouldn't even recommend either pattern at all. It's bad practice in all paradigms. Only have data flow through your execution path, don't have new "execution paths" flowing through your execution paths, such architectures tend to be over-engineered.

james_s_tayler
Do you have a good example of a reference architecture or implementation of a non-trivial system you can point me to?

I've recently gotten a copy of the book Domain Modelling Made Functional. I'm yet to read it, but I'm pretty intrigued by some of what I've seen and I have heard it comes highly recommend.

I'd be very keen to hear of other high quality examples of things people consider good reference material.

crimsonalucard
Functional programming is rare. It's sort of like the PS3 when it came out. Better specs across the board but harder to use and understand so it's hard for me to point to production level examples. Facebook does have one big project done in haskell you can look into that. Also whatsapp is done entirely in erlang.

Also note that the trend I see in the industry is not exactly movement towards functional programs but more movement towards borrowing features popular in functional programming as well as getting rid of classes.

Looking at your top priority books I recalled a slide from one of Brian Will's videos on object oriented programming: "Object Oriented Programming is Bad" https://www.youtube.com/watch?v=QM1iUe6IofM&t=326s. At around the 43:51 he pulls up a slide picturing several of these (and similar) books. Here is a rough quote: "I can tell you from personal experience of having read these books that you don't need to read them. They don't have answers, they aren't going to square the circle, and you are going to waste productive years of your life trying to live up to their ideals." Now that is just one rather controversial opinion, but we are talking about potentially wasting productive years of your life so I wanted to let you know that opinion is out there. That being said, it would probably be hugely beneficial to read a few of those books and then watch a few of Brian's videos (he has three or four on the topic) and sort out your own opinion. Also, Brian's other (not controversial) videos (dozens) are excellent for learning about programming. Also, Steve Krug's Don't Make Me Think is a keeper. I thought of it last night when I was checking out at a store. I stuck my debit card into the thing, entered my PIN number, then clicked the big blue button that said "Skip PIN". The woman behind the counter said "don't worry about it; everybody does that!"
There was an article on state in OOP posted here a few days ago that I found very thought-provoking[1]. The blog post and related youtube videos are pretty interesting as well[2][3][4].

[1] https://news.ycombinator.com/item?id=21238802

[2] https://medium.com/@brianwill/object-oriented-programming-a-...

[3] https://www.youtube.com/watch?v=QM1iUe6IofM

[4] https://www.youtube.com/watch?v=IRTfhkiAqPw

The author recommends watching Object-Oriented Programming is Bad.[1] I did, and Brian went into a discussion of dependencies (at ~20 minutes) and the implicit state-sharing that destroys real encapsulation and makes OOP a nightmare. He says: So if we're taking encapsulation seriously, the only real way to structure a program -- to structure objects as a graph -- is not as a free-form graph, but as a strict [tree] hierarchy." We handle message calls from one node to another by drilling messages from The Root down to the other ancestor. "No one writes programs this way."

We do. It's called Redux. The state is a tree, and each child is immutable and calculated via a pure function of the state and action (called a reducer). A message (called an action) propagates down every branch, and most ancestors remain unchanged, as they don't care about that particular action. So you have an explicit ledger of how state has changed, and figuring out why is trivial. State as an immutable result of pure functions gives you features for "free", e.g. time-traveling through your state. Debugging is a breeze. It's an absolute godsend.

(I realize the video is from 2016 and his opinions might've changed, but I think the speel is still valuable here.)

[1] https://www.youtube.com/watch?v=QM1iUe6IofM

lewisjoe
Yes, redux is a much saner way of mutating state, but the pattern is closer to FP than OOP. Remember Brian isn’t attacking state-management in the front-end or anything specific. He’s attacking the entire paradigm of object oriented programming.
I found this video by Brian Will was interesting when I was trying to learn about OOP[1]. It begins with some arguments, and there is a series of videos that follow where he attempts to illustrate the point. One of his newest videos is about an alternative form of OOP that he thinks works better.

[1] https://www.youtube.com/watch?v=QM1iUe6IofM

I assume that OOP is only meant for very large programs, and he unfortunately only demonstrates his ideas in smaller programs.

edit: added video author's name

Jul 09, 2019 · noobermin on Data Still Dominates
I'm not a systems designer, so I am somewhat ignorant to make this statement, but this sounds almost like "nouns-first" is the right thing, but almost every single one of those people cited in the article are anti-oop people. Moreover, OOP has generally fallen by the way side and been blamed for unnecessary complexity in some legacy systems from the 90s/00s. The moment you conceptualize your system as the interaction of concrete data types, OOP starts to seem like a logical paradigm to choose.

May be this is just in my head because I recently discovered this talk (ignore the incendiary title): https://www.youtube.com/watch?v=QM1iUe6IofM

wellpast
(The talk you link to is strongly anti-OOP. I assume you linked it as an example demonstrating your statement that anti-OOP is on the rise these days.)

To respond to your point, though:

Traditional OOP wants to meld behavior into the noun. Which should make the data-first (noun-first?) POV more apparent -- data isn't first-class when it's coupled to behavior as traditional OOP usually has it. So functional-oriented program is more data oriented as data remains first-class (ie decoupled from behavior).

0815test
Data is defined by behavior, even for "plain old" types. The point of "objects" is that sometimes you can implement the very same behavior in ways that are essentially isomorphic from the POV of your outside code, and want the freedom of switching out the underlying implementation at any time, and perhaps of validating complex invariants about the behavior your object has been designed for-- without letting implementation details dictate what sorts of behaviors you're going expose (the way, e.g. a "record" datatype exposes the equivalent of getters and setters, or a "variant record" exposes pattern matching, etc.).

This ("objects-based" programming; or programming with "abstract types") actually works fine. The part where OOP leads to real problems that make it inimical to true modularity is all about the tacked-on features of inheritance and polymorphism; specifically, implementation inheritance. Because that means you've started relying on the very interface you were supposed to define in order to implement some other behaviors implied in it, and then for good measure you're allowing that interface to change in practically arbitrary ways as new "derived" classes are defined. It's not surprising that this fails to work well.

chrisweekly
Yeah. It's _classical_ inheritance, in particular, that is typically associated with overly-broad criticisms of "OOP".
wellpast
> Data is defined by behavior, even for "plain old" types.

This is the POV of the OOP-ist, but it is not necessary and it is limiting. It's actually the "debate" we are having, so asserting it isn't proving it!

Functional programming has a complete story for polymorphism so OOP does not win on that account contrary to what you're implying.

I do think we have common ground in shunning class inheritance which is useless and a complete disaster.

However even without inheritance it seems to be that "objects" are provably replaceable by functions. (E.g., promote the implicit `this` reference to a first-class reference provided as an explicit arg to functions.)

I see no reason why data can't have opaque parts so data encapsulation doesn't seem to be a unique OOP claim either.

So then if objects aren't necessary for polymorphism and data encapsulation, then what are they good for?

meheleventyone
The fact you can make function like constructs in languages that don’t have them as a first class concept doesn’t mean functions are good for nothing. Likewise objects. If you can see benefits to making object like things in a different paradigm those still hold for paradigms that make objects a first class concept. If you’re asking why use a specific language with that concept over one you can implement similar concepts in then usually the argument is going to be about the ergonomics and expressivity of doing so. Similar arguments were had as functions/procedures crawled out of the primordial ASM soup.
0815test
> This is the POV of the OOP-ist, but it is not necessary and it is limiting.

How is it "limiting"? And if you want proof, look at the untyped lambda calculus - there you find data types defined entirely in terms of functions - pure behavior! (For example, the Church natural numbers are defined by the behavior of iterating some arbitrary function exactly n times; the Church booleans by taking two arguments and returning either the first or the second argument (which in turns makes it possible to define if-then-else, a sort of pattern matching); and so on and so forth.) It just so happens that this behavior-focused encoding is enough to express arbitrary programs - which is the opposite of limiting!

wellpast
> there you find data types defined entirely in terms of functions - pure behavior!

In every programming environment that I am aware of, such data-less functions you describe would be happily deleted without any worry to customers & stakeholders.

For example:

   add : Int -> Int -> Int
This may look nice on paper but on a real computer there are bounds to this purity. And anyway my program only becomes useful when actual integers are instantiated and appearing on stacks and the heap.

The "data-first" ideas we're discussing here ask one to stop obsessing over the functions and model the data soundly. You'll find any PL will do when operating over sound data expressions. This approach ime brings clarity and power to problem solving.

Theory divorced from practice is limiting. This is not a philistinic take, btw -- theory is supremely powerful when applied successfully for outcomes. But the "pure behavior!" you're talking about here seems too excitedly far away from practitioner-space.

noobermin
I'm sympathetic to your POV as it makes sense, but the author of OP even calls out FP at the end along with a list of what they seem to imply are not "data first" ways of designing systems. I'll go ahead and admit my bias here: rules are overrated, especially ones that propose "X first" at the expense of everything else because there are no one size fits all paradigms. You can find situations where orienting around types makes sense but you can always find situations were it doesn't make sense.

I also don't imply it's "50/50" as I really don't know what works or doesn't, it could be data-types first design works in 85% of the cases and so it's good to promote it or think in terms of design that way. I just don't like "X is the right way" talk in general, although it doesn't seem like the author is proposing this be a hard fast rule.

wellpast
I agree and I think rules are pointless. Everything is a tool and you pick the right tool for the job and that requires context and thinking.

However, having built systems in OO and then in functional, I've come to realize that the OO tools always have a surface of familiarity (`cat.meow()` vs `meow(cat)`) but are highly coupled (inflexible) while the latter, functional composition is not.

And if there's any objective measure to complexity it's a measure of degrees of coupling. And OO distinctly loses to functional there.

mpweiher
Hmm...I would say that cat.meow() has higher cohesion and lower coupling than meow(cat). Which is exactly what you want.

Maybe a different example would better illustrate the point?

combatentropy
What makes it clear to me is a fuller quote from Eric Raymond:

"Even the simplest procedural logic is hard for humans to verify, but quite complex data structures are fairly easy to model and reason about. To see this, compare the expressiveness and explanatory power of a diagram of (say) a fifty-node pointer tree with a flowchart of a fifty-line program. . . .

"Data is more tractable than program logic. It follows that where you see a choice between complexity in data structures and complexity in code, choose the former. More: in evolving a design, you should actively seek ways to shift complexity from code to data."

--- http://www.catb.org/~esr/writings/taoup/html/ch01s06.html

To paraphrase with a modern example, imagine a thousand lines of JSON, with deep nesting and all kinds of fields. It would still be easy to understand. Even a nonprogrammer could read it and find the part he's looking for (say, someone's address).

Compare that to a thousand lines of procedural C code, or even a thousand lines of Python. That would be much harder, and your nonprogrammer friend would throw up his hands and walk away.

The thing you hopefully learn after years of programming is that you can trade the length of one for the other. That is to say, you could simplify the JSON into half its length, if you make the code that processes it more complicated. Or you could simplify your procedural code by storing more complexity in your JSON data structure. The advice is to do the second thing, "to shift complexity from code to data."

Also, from another chapter:

"Data-driven programming is sometimes confused with object orientation, another style in which data organization is supposed to be central. There are at least two differences. One is that in data-driven programming, the data is not merely the state of some object, but actually defines the control flow of the program. Where the primary concern in OO is encapsulation, the primary concern in data-driven programming is writing as little fixed code as possible. Unix has a stronger tradition of data-driven programming than of OO."

--- http://www.catb.org/~esr/writings/taoup/html/ch09s01.html

noobermin
Thanks. Usually thanks comments are in bad taste on HN but this reply, especially the last quote is very enlightening. There is overlap but "data" here is not merely state of an "object" (which itself is an entity of abstraction).
dexwiz
Data Structures are more like Types than Classes. Any useful program is going to have Data Structures and Algorithms that operate on it. OP v FP are just different opinions on how that should be organized, either combined into a single object or separated into types and functions.
vageli
> Data Structures are more like Types than Classes. Any useful program is going to have Data Structures and Algorithms that operate on it. OP v FP are just different opinions on how that should be organized, either combined into a single object or separated into types and functions.

What is the difference between a type and a class though? Classes have modes of interaction through their interfaces, types can only be interacted with using specific operators. To me they are two sides of the same exact coin.

marcosdumay
And there's the problem, data types shouldn't interact. Verbs are a much better place to put your interactions.

I think the simplification of OOP as "noums first" loses too much. That "first" there isn't chronological, but mere visual weight.

There are patterns of OOP design that put data first, but there are also way too many that put behaviors first, but that behavior is owned by some data. At the other way around, people doing "verbs first" programing are even more likely to start with their data design than the OOP ones, because they lack of some boilerplate structure and need to get something to fundament their design.

jinfiesto
You can be nouns first and still be anti-OOP. I think the objection anti-OOP people have with OOP is the business of folding your verbs up with your nouns, not being "noun oriented."
i_v
That's an interesting take on it. I'm curious what gave you the impression that the example projects were written by anti-OOP developers. I feel like it could go either way. Even as I was reading the article, I was actually thinking to myself how I first observed discipline in data-first thinking from my functional-programming friends.
crimsonalucard
OOP is not data first. Or noun first. Objects are different from data in the sense that objects are a combination of data and methods.

In OOP the line between data and verbs blur into a combination of the two called an object. The object is a primitive and if your primitive is a combination of data and function you cannot program things in a way that has data first. At least you can't do it without making the code awkward.

FP is not, despite the name, a verb first language. It separates verb and noun allowing you to choose to build a program in a way that is noun or data oriented while OOP does not.

Data is a noun that cannot do anything except exist. Functions are verbs that cannot do anything but change things. Objects are a combination that are neither and thus hard to do data oriented programming if objects in your code exist as primitive building blocks.

All this article is saying is make the data a primitive building block.

mamcx
> Objects are different from data in the sense that objects are a combination of data and methods.

So data are models, functions views and objects controllers?

crimsonalucard
Data are structs, arrays, tuples, variables, sets, enums, etc. Data structures.
Jun 22, 2019 · 5 points, 0 comments · submitted by weinzierl
People are starting to use data oriented design instead of OOP. Data oriented design doesn't hide state, is generally faster and easier to comprehend as it doesn't abstract too much.

https://www.youtube.com/watch?v=QM1iUe6IofM https://www.youtube.com/watch?v=yy8jQgmhbAU https://www.youtube.com/watch?v=rX0ItVEVjHc

danmaz74
Data oriented design makes sense in video games where perfomance Is very important, but in most business applications having good abstractions which are flexible and easily maintainable is much more important than optimising for cache usage.
atoav
I tend to disagree — although I thought the same one or two years ago. Data oriented design doesn’t automatically mean you have to sacrifice useful abstractions on the altar of performance. You’ll have to find different abstractions and ways of composing them together to get a maintainable, flexible result.

In fact I find good data driven designs easier to maintain than good OOP ones..

eska
I keep hearing this from OOP proponents, but I just don't find it to be true in my experience. Programs written with DOD in mind have very clear data flow and only pass on and use data that is relevant. Programs written with OOP in mind primarily care about some notion of beautiful code and abstractions, which I find to be highly subjective. As a result they generally have very muddy data flow where e.g. unrelated data is passed around that isn't even required to implement a feature. This creates all kinds of poor modularization, dependency hell, huge monoliths, difficult testing (mocking, fakes, etc...), among many other problems. Whenever I have had to rewrite large parts of a program, I have always found it to be easier to do this in a DOD program rather than an OOP program. The biggest reason why DOD is used in video game programming to begin with is flexibility in mixing and matching functionality of game objects (entity-component-systems etc).
crimsonalucard
It is not muddy or subjective. OOP as described by JAVA is categorically less modular than functional programming. You feel it is worse subjectively because it is worse definitively, you just haven't grasped why yet.
Mar 16, 2019 · 125 points, 127 comments · submitted by tartoran
j_m_b
The problem for me in regards to OOP is the complexity related to the management of state. OOP encourages mutability and understanding the state of an object as its methods are called can be confusing when additional internal (and often times, private) methods are called. In functional programming, state is something acted upon by functions. It is as simple as f(x) = y. Reasoning in functional programming is much closer to the mathematics I've been trained in since grade school. In functional programming languages, mutability of an object is an explicit operation. It's easy to tell when state is being mutated visually from syntax. Mental overhead is greatly reduced when you can assume that your data structures are immutable.
mjburgess
Yes, but I/O is impure and sequentially dependent, unlike mathematics.

Maybe the "impedance mismatch" between pure-fp and I/O is too great, with the IO monad being the "leaky abstraction" of the FP world.

Then OO is not a bad solution to an irrelevant problem, but a pretty-good solution to a bad relevant problem.

EDIT:

To clarify: The "problem" is change.

Imperative programming relates sequential device-change over time, to sequential programming lines. OO programming is a structured imperative programming.

Pure FP langs model sequential change with (roughly,) lists of actions to-be-performed that are snaked through your program.

(Also: maybe OO's failure has more to do with its limited static analysis, type systems, than its model of change?)

jononor
Most of your application logic should not have to care about I/O. That is a concern which should stay at the edges. This way it is easier to reason about the program, and test it.
willtim
Why is the IO monad a leaky abstraction? Any function that returns an IO computation in Haskell, is still a pure function.
Rumudiez
Mathematics is sequentially dependent. Try 3/4==4/3 for a trivial example
mjburgess
Sequentially dependent in time.
asaph
3/4==4/3? Please explain.
discreteevent
Backus: Well, because the fundamental paradigm did not include a way of dealing with real time. It was a way of saying how to transform this thing into that thing, but there was no element of time involved, and that was where it got hung up.

Booch: That’s a problem you wrestled with for literally years.

Backus: Yeah, and unsuccessfully.

http://archive.computerhistory.org/resources/access/text/201...

mjburgess
Thanks for the quote!

Before I wrote that comment I was actually on the anti-OO side, and in writing it, I convinced myself that maybe the FP solution wasn't great.

Good to see this wasn't a mistake!

felipeccastro
“Mental overhead is greatly reduced when you can assume that your data structures are immutable”. I’ve been reading lots of articles claiming that but I still haven’t understand how that’s so. If you have fifty functions all acting on the same piece of state, why would returning new objects instead of mutating would greatly reduce mental overhead? Isn’t there still mental overhead in tracking which of the fifty functions made some transformation? Maybe this is something I would understand better with more practice in functional programming (which I don’t have yet), but if anyone could provide an example of this in practice I’d really appreciate.
vbuwivbiu
simply this: when any function returns a result, you never need to worry about anything else in the universe changing too. It's a self-contained operation with totally predictable results and no side effects.
hakfoo
On the other hand, if the "everything else in the universe changes" model is established and understood, that can be an excellent way to streamline and decouple things.

I could see it working well with a React-style component model-- update the state, and anything derived from it automatically changes to match.

vbuwivbiu
of course, if you prefer the 'anything could happen!' universe, have it at! And good luck to you
UncleMeat
But this is (largely) a property of the functions you write rather than the data structures. You can get virtually all of the benefit in the procedural world by just writing pure functions.
vbuwivbiu
when you have immutable data structures by default you get the additional assurance that other places in the code that previously used an input to a function can continue to work with their data without needing to worry that it might have been changed by its use by a function elsewhere, since that function cannot modify the data, only return a new 'version' (through structural-sharing)
felipeccastro
Yeah but when you do need to mutate state, why returning a new object is any clearer than modifying an object and returning it? Especially when the new object you return is going to be used to update a state tree later. Isn’t this a side effect too, even if more indirect?
dnautics
You don't have to worry about state mutating in the body of your functions, so when tracing or debugging the action of the function you can be very single minded and deterministic.

Its especially beneficial when you're doing multithreading work. I've debugged multithreading C++ and multithreaded elixir/erlang and fixing errors and identifying race conditions is night and day.

We wrote a front end in highly disciplined functional JavaScript on react with a single source of truth object in the center. I haven't touched JavaScript in a decade, and I could debug parts and add features with 100% confidence that I wasn't messing anything up (needed the frontend in a pinch so we hadn't done unit testing yet-i know I know, it's fixed now)

If you are curious, I recommend the video "boundaries" by Gary Bernhardt, of "wat" fame.

smuszel
Additionally you break up the implementation into two smaller tasks. First one being how to transform object A to object B. And second being how to wire up everything to pass object B to other functions needing it. In OOP we essentially do the two at once. It can turn into quite an overhead in complex system.
dnautics
> OOP encourages mutability

This is largely only true in the post-bjarne soustrop OOP era. The smalltalk or actor paradigms don't necessarily encourage state mutation.

pjmlp
Actually it was with C++ that I learned to control mutability via proper use of const and mutable, even before I got to learn Caml Light.
sisu2019
In theory this sounds great but in reality every major application, game, operating system and even website is written in an OOP style. Why is that? People should first answer that question.

Yeah, real existing software has flaws like every other thing in reality but at least it exists unlike a significant piece of fp style software. I like fp and I think it has a lot to teach but I think it's a bit presumptuous to advocate against a major paradigm that has actually proven itself with one that has failed to do so for decades.

And if OOP is so horrible why do so many people write OOP style PHP and javascript where they really don't have to?

Personally, I don't think OOP is bad per se, I just think the type systems of the main OOP languages are too limited and inflexible. Even so, you can accomplish amazing stuff in them. Just look at the Spring Framework and what it helps you do with so little code.

braindouche
>In theory this sounds great but in reality every major application, game, operating system and even website is written in an OOP style. Why is that? People should first answer that question.

Ok, try this on for size: OOP in general has one characteristic that makes it fantastic for large-team development, and that's extending over replacing. OOP makes it easy to never remove or change any existing code, and also "easy" to make changes or fixes by only adding more code. I wouldn't call it a good thing, but it does enable enormous numbers of people to all work on a codebase productively at the same time. I think this, more than anything else, is the power of OOP.

> And if OOP is so horrible why do so many people write OOP style PHP and javascript where they really don't have to?

Numbers. OOP supports big teams, so there are lots of OOP programmers in the wild. I genuinely think Javascript is sucking up to the Java developers of the world, and PHP is genuinely better for adopting OOP bits and pieces, but I'm not entirely sure why OOP devs and Java devs in particular seem to be immune to the industry mantra of "stay current and learn new things".

jpochtar
http://paulgraham.com/avg.html
mistrial9
fun read -- the last sentence included ! plenty to say about that article..

I get the sense that many commenters here, YNews in 2019, very much fit the description of a "Blub" programmer.. with the added twist that it is -giant-cloud-thing- platform and/or exciting web trends are my thing, to deepen the "Blub" point of view..

.. can't help but chuckle at the repeated and fairly clever jabs at ASM, considering it took M$FT ten years to make a windowing GUI that performed well enough on a PC, after the Mac OS was written in a lot of ASM.

sisu2019
But Lisp's object system is kind of famous. Where are the people beating the averages in pure fp languages? There should be a lot of really amazing software if fp is as good as it's made out to be and employed exclusively by elite non-blub programmers. There really isn't though, except maybe in finance where F# is doing quite well. And that's great but even F# is multi paradigm.
kazinator
My home-grown accounting system, written in a language with great support for functional programming, is based on objects. accounts, transactions, transaction deltas, ledgers, are all objects. Starting from a blank slate, a file is loaded which defines the ledger entries. These definitions are processed one by one, using mutable updates to the object framework. What is left is then the state of the ledger with all those entries and that can be subject to various queries and reports.
None
None
Fellshard
A fair bit of that can be easily explained as cargo cult - a fair number of developers simply believe, because it's how they've been taught and what's been stated as fact over and over and over, that OOP is just 'how you write code'.
sisu2019
is it really cargo cult if it works though?
discreteevent
Ok but objects have been successful for a very long time. And this is in a field where there are more potential early adopters than most. Programmers like new stuff.

I think they have been successful because in the end a lot of the world we deal with behaves like objects. Devices, processes, remote machines all accept messages and those messages have 'side effects' in that they change the future behaviour of that thing.

Fellshard
My current understanding (sure to change!) is this:

Objects and messaging are best at the boundaries of system components. The internals end up being far simpler to state in functional terms, where the side effects can be pushed to the edges with far less inherent complexity.

By assuming that objects are successful everywhere and always, it's really ignoring the regions where objects are more or less useful, painting over the picture with broad strokes.

By learning multiple paradigms, you're learning broad principles that map well across all languages, as well as principles that are stronger or weaker in some paradigms than others. This enables you to be much more versatile when creating systems than devoting yourself to the 'One Way To Code' mentality.

bklaasen
Credit where it's due; that sounds like Gary Bernhardt's "functional core, imperative shell": https://www.destroyallsoftware.com/screencasts/catalog/funct...

Previous HN discussion: https://news.ycombinator.com/item?id=18043058

vikingcaffiene
I've seen this posted here before. I take issue with anyone who gets onto a soapbox and announces "this might be the most important video you've ever watched" and then proceeds to espouse their opinion about something. It's egotistical and it immediately sets up any dissenting opinions as Obviously Wrong. I call BS on all of it. OOP can be written well. I've done it. I've seen it done by others. When you need a strong domain layer and strong data integrity it can really pay off dividends. I think what people are really trying to avoid when they say "OOP is bad" is poor design and entangled concerns. In general favor composition over inheritance, strongly defined data contracts, and a clean separation of concerns (business logic from presentation for instance) and you will find yourself with more maintainable and easier to read code. But thats just like, my opinion man. :)
mrkeen
This advice/reflection could apply equally to any style of programming, except for one particular snippet. You haven't made or refuted any OOP-specific claims. Separation of concerns? Egotistical soapbox speaker? Strong domain layer? What do they have to do with OOP, as opposed to just P?

Except for this: > favor composition over inheritence

Yes! Inheritance is OOP-specific, and I agree that you should avoid it.

peteradio
But why? Why avoid inheritance?
LoSboccacc
if done improperly one ends up having to maintain backward compatibility in the parent object not just on the actual interface but also in the internal state. basically makes it too easy to violate incapsulation

one needs not to avoid it completely but need to be aware of the pitfalls

vikingcaffiene
Inheritance is a powerful tool. And like anything powerful, you need to think very hard about it use and assess whether another approach might be more well suited to what you are trying to accomplish. In my experience the reason people use inheritance is often simply to share common functionality. There are a lot of ways to get that done that don’t require inheritance.
mistrial9
> poor design and entangled concerns

good on you to call BS a bit, but others have mentioned management of state specifically.. so "nouns" are ABCs, "verbs" defined, but after runtime for a while, and getting hammered or other difficult conditions, what is state like ?

good OOP can be really useful, without being a religion.. personally I would build general-purpose objects here and there to save some tedious decomposition..and the resulting seperation of code and concerns was fine .. specific things get specific code, while one or two item constructs somewhere off the beaten path might get lumped into a collection of "util" or similar.. its ok - it takes some practice and thinking ..

0815test
> "this might be the most important video you've ever watched"

This is standard practice on YouTube, for better or for worse - same with the usual appeal "hey, you can help me by liking, commenting and subscribing!" at the end. (I have not clicked on this video, so I have no idea if anything like that is in there too.) Gotta drive those "engagement" numbers!

anonuser123456
I think one of the reasons anti-OOP opinions are so strong is that OOP was promoted as the end all savior of programming. At my University it was dogmatically emphasized.

"OOP" (e.g. subtype polymorphism) is useful for some problems, but worthless and kludgy for others; it's a hammer pounding lagbolts. A generation of programmers (mine) missed out on the richness of Lisp/ML flavored languages.

I didn't really come to Lisp/Ocaml until a decade after I'd been programming and after embracing it, I can't imagine going back.

Thankfully were in the multiparadigm era where modern languages are adopting the best of all world's.

zaphirplane
interestingly Lisp/ocaml/clojure rank low in popularity, clojure shows it’s not because of libraries. That has to mean something other than libraries or unenlightend people. Idk maybe there is too much complexity in those languages and philosophy
Fellshard
Learning new languages is considered to be one of the highest costs a developer can pay. To be fair, there is a cost to picking up a new language, but nowhere near as high as is often believed, especially after one has learned two or three significantly different ones.

I'd argue that those languages don't see as much use in great part because they are not the first languages people are exposed to, and therefore most decide it's not worth the effort to learn them.

zaphirplane
Idk about that People are going out of their way to learn, go, typescript, swift, Kotlin, Scala (kind of)
0815test
The biggest problem with OOP is arguably inheritance, specifically implementation inheritance. The basic issue is that "protected" methods may be extended arbitrarily by a child class, with zero indication of what properties might in fact be relied upon by methods in the parent; this inevitably leads to a rather intractable version of the Fragile Base Class problem.

This pitfall of open-ended implementation inheritance (a.k.a. "open recursion"), which is precisely what "inheritance" per se provides over the well-known (and often used) combination of "object-based" composition and "interfaces"/traits/type classes, is pretty damning for OOP itself.

ryanmarsh
Brian's video is one of the most influential bits of wisdom I've received in my career. Up until this video I did not have a language for explaining the problems I ran into trying to build OO systems. It also helped me understand why writing procedural-functional code felt so natural and easy.

I was a die hard OO/UML guy. I even contributed to various open source software projects for a model-driven-architecture framework, a UML editor, and integrations with Rational Rose. I was an evangelist for good OO practices, SOLID, etc... As a development coach I was quite fervent.

Looking back on that I feel like a fool. When I read the code refactoring examples from Uncle Bob and others I see all the problems Brian talks about in his video (and more). OO was a nice idea but we got the granularity and implementation wrong.

holdenc
A 44 minute powerpoint on why OOP is bad? Please refactor into separate self-contained and neatly presented topics each with their own methods for breaking down this argument.
tyingq
Here's the medium post from the same author that goes with the video: https://medium.com/@brianwill/object-oriented-programming-a-...
astazangasta
This is someone who is confronting basic limits of representation and information flow and blaming OOP. There is no one best way to organize code just like there is no one best sentence to describe a rose.
api
"There is no one best way" summarizes what I think is a major unheralded realization in software engineering in the past 10 years.

Before that it was the search for the One Way. OOP and functional programming were probably the two biggest opposing schools during that era, but now the trend is languages that easily allow both plus plain vanilla procedural programming. It's the programmer's job to pick a paradigm for the problem being solved.

tyingq
I'm curious if this is the way older and more established engineering progressed. I would be interested in how, for example, designing and building a bridge to suit a specific use case has evolved over time.
0x445442
Software not being bound by physical constraints like other engineering disciplines is a huge distinction. So much so that I think software development is closer to writing a novel or movie script than it is to building a bridge. However, I would say the closer the software is to bare metal the closer it is to "real" engineering.
astazangasta
There are two major concerns in software, performance and legibility. These concerns are somewhat orthogonal but neither can be abandoned, and the challenge is balancing them. By contrast in bridge-building (etc.) the two main concerns (performance and aesthetics) have been largely separated by discipline, into engineering and architecture, the former a purely mechanical discipline, the latter almost entirely artistic.

The main result of Modernism has been the subservience of the latter to the former, and in general the almost wholescale abandonment of aesthetic concerns. This is starting to come apart a little bit as people realize that this separation is unhealthy, and maybe we shouldn't build brutal, ugly flyovers through our cities because they have measurable effects on happiness, and thus property values, etc. (i.e., aesthetic concerns have functional consequences).

Similarly I think many software "engineers" take a long time to realize that one of their main functions is writing code that others can read; this is an aesthetic, artistic discipline that I think many developers reject as outside their domain. This, too, is starting to come apart as we slowly figure out that code's maintainability is a key determinant of its long-term success - that is, aesthetic concerns have functional consequences.

slavik81
"there is no single development, in either technology or management technique, which by itself promises even one order of magnitude improvement within a decade in productivity, in reliability, in simplicity"

~ Fred Brooks, No Silver Bullet (1986)

tyingq
The explosion of variety has actually pushed the other way. It was expensive, but MVS shops could push out highly available apps with a consistent UI very quickly.

It seems we've really only made progress on unit cost and ubiquity.

I think this is roughly why cloud is popular. It's not cheap, but if you're using their standard pieces (RDS, lambda, ECS, ELB, CloudWatch etc), you're working in a defined box with fewer choices.

yxhuvud
From the post; "The problem, however, is that, while organizing program state into a hierarchy is easy, OOP demands that we then organize program state manipulation into the same hierarchy, which is extremely difficult when we have a non-trivial amount of state. Anytime we have a cross-cutting concern, an operation that involves multiple objects that aren't immediately related, that operation should reside in the common ancestor of those objects"

No, OO does not make any demands like that. You are totally free to make objects and classes out of processes and algoithms, and that is a good tool to do the kind of cross cutting concerns the article talks about.

karmakaze
So OP somehow inferred that OOP requires operations to only be carried out by 'ancestor' objects and fails miserably. What they call 'ancestor' objects also have nothing to do with OOP in hierarchy as it is not an is-a relationship by rather ownership/has-a that is common in many styles including composition over inheritance. Basically they don't know what they're talking about.
nfrankel
Could we please stop this kind of useless statements? Aren't we developers supposed to be scientific-minded?

There is not such thing as "bad" or "good" in absolute. There are paradigmes that work better in certain contexts - and I use the word "context" in very general way here - and some that work worse.

If my consulting experience has taught me something, is that "it depends" is a valid comment most of the time. By the way, I also learned that if you stopped at this comment, you're not a good consultant.

platz
This conversation would be improved by responding or refuting to the specific points made in the video instead of generalized comments
bunderbunder
I really liked the first half - he provides some insightful thoughts on both why OOP doesn't quite deliver on the promise, and why it continues to be popular anyway.

I am also becoming increasingly enamored of procedural programming as a default approach. Functional is also good - it's one of my first loves - but I find that it can be similarly prone to encouraging premature abstraction. Like OOP, that problem isn't going to become so apparent until you start using it in a large, long-lived business system with ever-shifting business requirements.

That said, I think that I've got to part ways with the video around about the part where it switches to talking about how the speaker thinks good code should be structured. Especially the bit about not keeping functions small - the problem with that is, it makes it way too easy for spaghetti code to sneak in. In the same way that, in the heat of the moment, a developer in an OO language is going to start tangling together the connections among objects a bit too liberally, a developer working in a 300-line procedural function is going to start fiddling with any variable that happens to be in scope a bit too liberally. Factoring out your functions does mean you have to name all those functions (which, I realize takes effort, but I also can't agree that it's a waste of effort), but it also serves as a way of making sure everyone stays honest about shared mutable state. Maybe it wouldn't be so bad in a language that has that "nested functions that aren't closures" feature, but, like he says, such a language does not currently exist.

jstimpfle
Please excuse my sibling post. I realize I put not enough effort into actually reading your comment all the way through. I agree with what you say and want to add as an aside that I think LLVM has the inline-function feature that you mention.
platz
His style perscriptions can be directly attributed to Jonathan Blow (which they match) who he also mentions in that section.

Also I think the mention of golang is telling which I think is an implicit bias in his preferred style reccomendations.

polarcuke
Ruby and Swift (and other languages I'm pretty sure) allow you to have named functions nested in functions
bunderbunder
What the video specifically suggested was not any old nested function, it was nested functions that do not capture upvalues from their context.
totony
PHP has those (e.g. function() use ($var) { })
jstimpfle
The small-versus-large-functions discussion is not about spaghetti code. It's about the question whether you should chop one large block of first-do-this-then-do-that code into smaller independent blocks and then call them in that very sequence from a superordinate function.

In general I totally agree that sequential code should just be sequential, and it should not afford more functions. Because, the each time one looks at those additional functions, in your standard programming language, the first thing one must ask oneself is, "what is the context in which this function must work? What are all the callers of this function?". In simple, sequential code, the answer is often more clear. At least, it's clear that the block of code is really only ever "called" from one place.

The disadvantage is that the block can see unrelated variables that were defined higher up in the same function - or one must add a level of indentation everywhere to protect those.

bunderbunder
My concern there is not that a monolithic block of sequential code is inherently spaghetti code. It's that their natural tendency is to spaghettify over time.

Clean 300-line functions form an unstable equilibrium point; it requires constant effort by someone who cares about code hygiene to keep them clean. More so than factored code.

api
OOP is a way of thinking about and structuring your program that works well for some problem domains and not for others. Like other paradigms it can become dogmatic and be overused. Also like other paradigms it became a huge fad for a while and now there is a backlash.
type0
Actually - Object-Oriented Programming is Good* https://www.youtube.com/watch?v=0iyB0_qPvWk
platz
Namedrops golang again.. seeing a pattern here.

The claim that primitive types are better than interfaces (inside modules) reveals that he is comfortable with golang style. But this point misses that you can do _more_ things when you know the full concrete type of something, than when you program generically, only depending on the minimal requirements of what you need, which in turn opens up flexibility for the caller (constraints liberate).

Of course, one doesn't think too hard about this in golang, lacking generics

hevi_jos
It is quite obvious to me that the author is ignorant on the history of computing.

The reason of the popularity of OOP is way longer than java, Xerox invented the graphical desktop and ALSO OOP.

When Steve Jobs was ousted from Apple he created NEXT because he believed OOP was the next big thing. It was, and it became the foundation of MacOS X. Microsoft copied Steve Jobs in Windows with MFC. Java copied all of them.

In the words of Steve Jobs, developing in OOP is not faster than not using it. The big difference was once it had been created, it can be reused easily. That was essential for complex systems. It became obvious for companies.

There is this religion today of functional programing, people come to me and say, look how great this is, without state parallel programming is so easy, now you can use 32 processors at the same time. Great!!, until we measure performance and the thing goes 50 times slower. So now you can use 32 processors for what used to take one.

Don't get me wrong, we use functional programming when it is the best tool for the job(it removes lots of bugs), but it is not panacea.

None
None
adamnemecek
Functional programming has little impact on performance.
pjmlp
Only when proper use of memory isn't part of performance.
zaphirplane
Probably talking about Java’s implementation which takes a while to warm up
goalieca
Oop is slower than functional in many cases. The highly optimized java stack isn’t that fast and still uses oodles of memory. And then there’s languages like ruby which are practically slower than writing shell scripts.
pjmlp
Functional generates tons of garbage and requires a very good concurrent generational tracing GC, more so than OOP languages.

Only thanks to researchers like Simon Peyton Jones[1], did functional language compilers improved their code quality.

[1] - https://www.microsoft.com/en-us/research/publication/the-imp...

willtim
It's actually harder to write a GC for a language like Java with both rampant mutation and plenty of garbage!
pjmlp
I only accept CS papers about it, do you have one at hand against Java favouring some random FP language instead?

Something of this level of quality, not random assertions on online forums.

http://kcsrk.info/multicore/gc/2017/07/06/multicore-ocaml-gc...

willtim
There are a few papers about Haskell's GC by Simon Marlow where this is discussed. The absence of mutable references is a big win for writing a concurrent collector.
pjmlp
I don't recall any of Marlow's papers having a table comparing performance of Haskell tracing GC implementations versus the tracing GC implementations available across several JVM implementations.
willtim
You never defined what you meant by a "good concurrent GC", only now are you asking for "performance" numbers.

My point is that writing a GC for Java has in fact proved very difficult. It took Sun and Oracle many man years and different GC designs to get where they are today. So it seems Java also needs a "good" concurrent GC. With both functional and OOP languages generating a lot of garbage and sharing language features, I don't see a big difference in requirements in practice. And sure enough, Clojure/Scala seems to work well using the JVM GC and F# seems to work well with the .NET GC too.

I think the burden of proof rests with you and your statement that the concurrent GC situation is somehow more challenging for an FP language.

> I only accept CS papers about it

Me too

anonytrary
Not shipping a working product before your deadline is bad. How you get there is up to you. OO isn't necessary but it can get you there. In a perfect world where deadlines didn't exist and everyone writing code was doing so for academic purposes, maybe OO wouldn't be necessary.
specialist
Good grief.

The reason that OO, FP, functional decomposition, entity relation diagrams, methodology de jure sucks is because modeling is hard.

--

These rules apply to all programming paradigms:

Favor composition over inheritance.

Try to not share state.

Favor dumb objects over active objects.

Favor shorter call stacks, less indirection.

Try to bunch like things together.

Try to DRY.

pjmlp
The irony of the anti-OOP bashers is that all successful GUI frameworks are OOP based, even those written in non-OOP languages like C.

Likewise all the functional programming languages that get used as example, are also not pure FP, rather multi-paradigm, also supporting concepts from OOP.

"FP vs OOP: Choose Two by Brian Goetz"

https://www.youtube.com/watch?v=HSk5fdKbd3o

willtim
GUI frameworks have always been OOP-based because everybody was copying Xerox Parc. But even the most successful were not always easy to use (composition and control-flow/concurrency being particularly awkward). Modern GUIs are all based on HTML/CSS these days anyway and certainly not always OOP, as demonstrated by frameworks such as react.
pjmlp
Those modern GUI based on HTML/CSS don't work at all without JavaScript.

Prototype inheritance is also OOP.

willtim
I'm not a web developer, but I don't think the OOP features of JavaScript are really used much. I once saw some jQuery code and it looked pretty functional to me.
pjmlp
Other than those exposed via the Document Object Module.
discreteevent
I think that is a bit like saying Xerox parc guis were all pixels which certainly isn't oop. Modern guis are mostly OO code that targets the Dom or generates HTML on the server
jelling
Where does Domain Driven Design fall? DDD typically has service class that operates on multiple business objects in a pipe-line like fashion. Being business programming, there is always side-effects but usually handle via repository or db manager classes. I.e. no active record.
ryanmarsh
It is perfectly sensible, easier even, to apply DDD concepts to small functional services. Define a bounded context and aggregates. Under the hood (inside the context) there are a number of strategies for handling side effects, data structures, and state transitions.

I'm finding DDD + functional languages + serverless architectures work quite well together, so far.

vitriol83
one issue with OOP in practice that I've seen is the entanglement of the domain representation (member variables of a class) and the varied operations on that data (methods). Classic OOP encourages you to manipulate objects by methods rather than free functions, which combines potentially unrelated functionality in the same object.

my rule of thumb with objects is to keep the methods to a minimum, to the extent all classes are either interfaces, implementations of interfaces or pure data classes. obviously this approach will be natural to ML programmers.

ineedasername
This seems like just another "bad" == "I prefer a different type of tool."
None
None
viach
What else people can do - videos, articles - just to avoid learning a little bit of Java? Stop that laziness and learn OOP properly, you'll find a good use for it!
chriswarbo
> Stop that laziness and learn OOP properly, you'll find a good use for it!

This is my biggest problem with OOP: proponents keep shifting the goalposts to avoid criticisms. If someone follows OOP practice, and it doesn't work out perfectly, then they must not have been doing it "properly". Hence "OOP" becomes a nebulous term, encompassing a whole bunch of approaches (encapsulation, inheritance, subtype polymorphism, dynamic dispatch, SOLID, MVC, etc.) but if any of those don't work in some situation then they mysteriously don't count as 'proper OOP' in that case.

I used to be very deep down the OOP rabbit hole (oh the joys meta-object protocols!), but these days I tend to stick to functional programming. I wouldn't claim it's the best way to program, and there are different tools for different jobs, etc. but one thing I've taken to heart is that we should try to make the easy thing be the correct thing.

An example of this is static type systems: it's possible to write correct code without types, but it's much easier to get things wrong. Type checking rules out a lot of those wrong things, which makes it more likely we'll do the correct thing (note: I'm not saying static types make things easier, I'm saying that the easiest thing to do in the presence of static types is usually more correct than the easiest thing to do when there are no types). Automated testing is another example, as is purity, effect systems, capability models, etc. Even the fact that Java forces us to write a class in a correctly-named file just for "hello world" is an example of making the path of least resistance more "correct" (although I disagree with Java's notion of what's "correct").

Even if we concede that these complainers aren't doing OOP "properly", that just means OOP is fraught with gotchas, misaligned incentives and lacks objectively checkable criteria. I wouldn't want to pursue any practice where earnest, researched attempts to follow it not only lead to the very problems that it claimed to avoid, but is met with advice to follow the practice "properly". Just look at how much of softwareengineering.stackexchange.com is bogged down in philosophical pontificating about the nature of OOP!

As for your specific claim, after doing OOP in several languages for many years, professionally, academically and recreationally, I count Java among the worst (PHP is slightly worse). I could say that if you want to do OOP "properly" you should try Smalltalk, but that would be yet more philosophical snobbery (you should instead try Smalltalk because it's a great language ;) )

viach
> OOP is fraught with gotchas, misaligned incentives and lacks objectively checkable criteria

Like, almost everything in programming these days (especially the frontend part)?

I actually like how functional code looks like, especially ML dialects - OCaml, Haskell, F#

What stopping me from trying to use these languages in prod is the lack of tooling (mostly refactoring), in the sense what Idea can offer.

And when you have >3 people in a project with a language which has no mature refactoring tools, there is a problem then, a big one. Imho of course.

anonimito
Have you tried HIE/hlint for rrfactoring haskell code?
chriswarbo
> > OOP is fraught with gotchas, misaligned incentives and lacks objectively checkable criteria

> Like, almost everything in programming these days (especially the frontend part)?

Everything has problems; that doesn't mean everything is equally problematic. My point is that we should favour practices which are unambiguous and encourage objectively good things, and that OOP isn't either of those.

W.r.t. functional programming, I wasn't trying to argue in favour of it specifically here. I write a lot of procedural code, and keep looking for opportunities to learn/apply logic programming ;)

kyberias
Can't agree with his suggestion on long functions and comments.
namelosw
There are a lot of mention on functional programming and OOP comparison in this thread. There's my 2 cents on the topic:

1. OOP is not necessarily bad.

2. The original OOP should be Smalltalk-like languages (messaging), but the term OOP we refer today basically related to Simula-like languages (inheritance, polymorphism).

3. OOP and FP are not exclusive. Language like Scala you can have a 'case class Stack[A]' with a method 'def push[A](a: A): Stack' returns new stack. First, it's a class and be able to have methods, inheritance etc. Second it's an ADT (Algebraic Data Type) and without any function with size effect. So both OOP and FP still makes perfect sense.

4. Main stream OOP languages design are mostly terrible. (Basically the 'Blub language' according to Paul Graham, I'll call those language Objective-Blubs because I want it to be a mainstream OO language without hurting someone).

5. There are a lot of arguments against Objective-Blub or OOP itself are related to state, side-effect etc. These are partially true. But I can't say stateless and pure is totally better than other approaches, I just feel better when I'm tackling complex domain so code does not affect each other in a crazy way. However if the whole program is pretty easy to make sense for you. For FP approach there is no obvious advantage over Objective-Blub. In this case choose the one with higher velocity.

6. The core problem that Objective-Blub to me is not simple state or side effects. It's the wrong/implicit modeling, if you are not modeling a problem, 9/10 you cannot address the problem. It's would bite you again and again. For small application these are fine, for large application these omitted modeling could be a real problem. But there are so few people mention this explicitly, please allow me to list some of them here:

a. Quick example - NullPointerException: Not modeling nullable concept makes you handle null everywhere. By explicit modeling Optional/Maybe/Some it could be resolved.

b. In Objective-Blub objects are reference type by default: Which means it's assume you only use the object in this specific machine and thread. Objective-Blub programmers always complain about object-relational impedance mismatch, and then they blame SQL. But the real problem is Objective-Blub itself. For Objective-Blub you have to throw away all the methods and references. Not only SQL, JSON or other serialization is also a big deal. If you use FP languages you just map tables to an ADT which is not a big deal. There's no assumption on identity on FP language at all, if you want an entity, just give it an id field. That also explained why FP languages is more concurrent friendly, because same data on different machines are still same data.

c. Sub-type polymorphism does not let programmer do the correct modeling easily: ADT have sum and product type. That's how you describe domain types, it's so straight-forwarded. Done. While languages like Objective-Blub have class and enums respectively, but no parametric enums. You have to write less obvious code to model simple concept like 'Payment = CreditCard(no, cvv) | Cash(amount) | FreeCoupon'

d. Sub-type polymorphism means strong assumption: This is so called inheritance, which encourage you do strong assumption like a Person extends a Head, which works but implicitly indicates a Person is a Head. This is ridiculous but if you convert Person and Head to some business type and services you can find too many code bases having this problem.

e. Sub-type polymorphism is under-powered than other polymorphisms: Less powerful is good when it's enough. But it's a huge problem when it's under-powered, which means you have to hack all the way round - like with old day Java, if you loop through an array, you have to cast type to every element. This is insane for a verbose statically typed language. Language should focus on simplify parametric polymorphism like OCaml or Haskell does to guide programmer choose a better way by default. Statically typed FP languages usually model effect with parametric/ad-hoc polymorphism, which could be a huge deal of separating dirty world concerns - like in Scala you can have your domain service accept F[_] as effect type parameter without knowing what this effect would be, it could be database IO or random generator or totally different abstract things.

f. Methods are everywhere: In Objective-Blub you have to write all methods in same class. So if a class having 100 methods is considered a code smell. And someone refactored them, move some of them to other classes and extract some of them to a new class. That's typically one reason why large code base are so hard to read, because typically in FP languages it's no big deal when you have hundreds of function operates on the same type, you just split them in several files if you want. For those extracted class and moved methods, they largely blurred how domain type and logic should be, because you have to create a new concepts, or move concepts to other places just because the old concept is too big.

g. Less expressive also blurred things: For the first time I was looking at a code base with design patterns everywhere I was so confused. Most patterns are the problem that language is so constraint that it cannot express simple idea, like TypeScript allow Partial<T> in constructor it would eliminate most of the builders. Like singleton and static properties could be addressed with Scala object. When a code base is filled with BarFactoryBuilder etc, that means the language itself does not modeling these common patterns at all. This make people(both reader and writer) fighting with languages instead of just expressing domain business.

shmooth
i love any kind of 'hate' article, and this guy is hilarious, so +1
shmooth
yeah, that was pretty good. i guess OOP is not the end-all be all. prob would have been more useful if this was produced 10 years ago instead of 3 years ago. is anyone still using OOP?
wowJavaScript
And watch, I bet the fix is to use JavaScript instead, because it's better.
randomsearch
s/bad/unfashionable
nathanaldensr
Except it's not unfashionable. It's used by millions of programmers who just want to get stuff done. It's used by thousands of companies who don't really care how the native instructions are eventually generated. It's used by individuals and teams, application developers and library authors.

This premise of this video is flawed from the beginning and the whole thing is basically a gigantic straw man.

mrkeen
He has reduced OOP to polymorphism/encapsulation/inheritance. Is that what you mean by the straw man?
peteradio
He specifically says inheritance and polymorphism are irrelevant in the video. His problem is with poor encapsulation which is not specific to OOP.
0x445442
Not sure if nathanaldensr means that but that's what I would say is the straw man.

Also, it's been my experience a lot of developers have a lot to learn about OOP principles. The most common OOP idea that's seemed to have been lost is asking an object to reason about its current state. If I had a nickel for every time I see code like below...

String fooJson = new Gson().toJson(foo, Foo.class); or

Double totalTax = TaxHelper.totalTax(orderItem.getCityTax(), orderItem.getCountyTax(), orderItem.getStateTax());

block_dagger
It seems the author has not learned how to use OOP appropriately. His main argument can be summed up as “it’s hard to name things and hard to compose things” and that seems to apply to all programming.
mrkeen
Can you please elaborate? What is his inappropriate use of OOP and how would he use it more appropriately?
Wilduck
I don't think you understood his points.

When he talks about the "kingdom of nouns" he's not complaining that the problem with "Manager" classes is that they're hard to name. Instead, the argument is that these manager classes are hard to name because you've reached a point in encapsulation where the association between behavior and state in inherently unclear and overly abstracted.

I think the author would agree that all programing deals with the difficult problem of composition, however, the argument in this case is that OOP introduces unrealistic constraints on composition. The argument in this video is that encapsulation and the single responsibility principle requires you to choose between a difficult to maintain tree-based object hierarchy, or to abandon encapsulation, and that both of these are sub-optimal choices.

Finally, I think the author would agree that he "has not learned how to use OOP appropriately" but would go one step further and say that "it's impossible to 'use OOP appropriately.'"

rcdmd
You can make any number of arguments why X, Y or Z is bad (or, "considered harmful"). The truth is, if you want to get stuff done, objects often fit the domain well enough and put state in predictable places. A bandaid here or there, "friend" classes and so on may be required. But, you'll get stuff done even if it's not in some perfect stateless beauty.
ravenstine
In my experience, the thing that's wrong about object-oriented programming is not the object-orientation itself, but the over-application of it.

- Sometimes more "procedural" programming provides better clarity. At other times, object-orientation is a cleaner approach. Neither should be a replacement for the other at all times.

- The idea that objects should reflect how we think of real objects in the physical world probably needs to die, or at least not be treated as a standard for object orientation, since objects in reality often do not fit into neat categories and hierarchies. Because reality is dirty, as is virtual reality, unanticipated exceptions to the rules end up causing OO zealots to create hack solutions that end up being rigid and less obvious to other programmers. The simplest example I can think of off the top of my head is the Fat Model Skinny Controller paradigm in MVC programming; since a model is often looked at as a representation of real-world objects, a programmer thinking in OO is likely to stick every conceivable property and behavior around the imaginary object into the model code, which sometimes results in files thousands of lines long with code that doesn't need to have anything to do with database abstraction. In such cases, a lot of code related to the concept behind a model would be better handled by helper functions or other classes.

pacala
Well duh. We’ve been sold object oriented platforms for decades with the insistence that everything is an object, hiding its internals from the world. There was tepid support for representing plain data. At the heyday of the madness people were busy building object-over-network abominations like CORBA. Even today, the most popular enterprise platform, Java, does not support value types. In the free world, the widely used Python platform has added dataclasses only as recent as 3.7, the current version. No wonder OO style is widely overused.
contextfree
isn't "object over network" basically microservices?
discreteevent
No. Microservices pass data over the network. Distributed objects get handles to remote objects and then make calls to them. Sometimes there could be very many of them and it all got very complex and had poor performance. Microservices are still object oriented because each service is an object and the data being passed is a message. They are big objects. Alan Kay said that one if the mistakes with OO was not making objects bigger.
pacala
Indeed, objects should have been larger. As large as a module. Perhaps with interfaces implemented by different concrete modules. Like non-oo programming language were doing, circa late 80s [modula 3, sml].

While at that, “message passing” [aka goto with arguments] is too fine grained of a concept, what people need 99% of the time is a structured function call.

0815test
CORBA actually supports both "object handle over network" and "ship some actual local object as part of a request/response". It's basically a way of addressing typical FFI/IPC concerns in a way that's actually network- and location-transparent, and that thus also addresses the concerns of distributed programming (for example, making something network-transparent introduces network faults as a possibility, and your system needs to deal with them appropriately!)
nurettin
It could be, if you also send the entire object with all its dependencies along with a remote procedure call. Kinda expensive and misses the point, though.
pacala
No! Micro services are value-over-network, hopefully with idempotent semantics. CORBA is object-over-network, with clients holding references to server objects and a protocol that passes around object references over the network. It is true that one can do value-over-network within a CORBA environment by throwing away 95% of the features, but that is not idiomatic CORBA and was sneered upon as not object-oriented enough. This is a case of too many misguided features misleading users down unproductive paths, possibly even worse than selling [a-z0-9_ ]* as the ultimate programming language on account that there are subsets of this language that are actually useful.

http://www-cs-students.stanford.edu/~dbfaria/quals/summaries...

pjmlp
Quite right, micro-services are the millennials rediscovering SUN RPC and XML RPC, while writing spaghetti structured code with a network in the middle.
stcredzero
At the heyday of the madness people were busy building object-over-network abominations like CORBA.

There was even an unpleasant period of time in the 90's when people tried to make some of the Linux OS distro end-user apps run off of CORBA to bring about the interconnected "sea of objects" vision, slowing things down a lot.

No wonder OO style is widely overused.

It's overused in part, because it's easily sold. It's easy to make sound-bites out of the doctrine. At the same time, it's a bit nebulous and it's easy to describe all of reality this way at first glance. (That said, in the right hands, it can make for some dandy, clean software. The tricky part is the "right hands.")

Basically, software is organizational politics. Software methodologies are dogma, with nothing to back them up, except maybe some savvy design and at times some mathematics. However, these aren't sufficient to deal with the complexities brought in by business needs, the real world, and the complications of developer communities.

We're back in the alchemy days of the programming discipline. This is perhaps why minimalism often rules the day. Do as little as possible. Make do with as little as possible. Make apps and modules as small as possible. As much as possible, do no harm.

smileypete
>Basically, software is organizational politics.

I'd go further to say that software management is (often, mostly?) organizational politics.

Software itself is about the flow of control and data, trouble often follows where dogma obscures this fundamental.

stcredzero
Software itself is about the flow of control and data, trouble often follows where dogma obscures this fundamental.

Trouble always follows where dogma conflicts with first principles and empirical data.

More correctly, a significant part of software development is organizational politics. The "flow of control and data" inevitably gets you embroiled in that.

None
None
0815test
> There was even an unpleasant period of time in the 90's when people tried to make some of the Linux OS distro end-user apps run off of CORBA to bring about the interconnected "sea of objects" vision, slowing things down a lot.

That was a thing on the GNOME desktop (GNOME being short for GNU Networked Object Model Environment). The CORBA framework was called bonobo, and it was basically a very early version of what's now achieved via dbus. KDE had its own equivalent, known as DCOP. AIUI, both systems were replaced altogether when dbus became a thing.

agumonkey
Point 2 rings true to me. The idea that you could model reality in a layman manner is borderline madness for engineering. You want to encode invariants and properties that are far from the superficial taxonomies you get fed in school.

Object orientation can provide a cute encoding of abstraction layers ala SICP to avoid dealing with a bunch of dangling functions:

scarface74
One of the seminal books that people read about object modeling “Domain Driven Design” by Eric Evans writes about “transaction scripts”. Not everything needs to be modeled.
stcredzero
Not everything needs to be modeled.

The thing about Smalltalk, is that it adheres very closely to "everything is an object." This means that even low level mechanisms in Smalltalk have to allow a very nimble use of objects. This means that there can be serious cost/benefit mismatches when translating libraries/patterns/designs from languages like Smalltalk to others. Creating a lambda in Smalltalk is trivial business as usual. Other environments require more thought, have more limitations, have higher costs of their use. Factories are how you do normal operations in Smalltalk. In other languages, they become infrastructure that needs to be maintained.

Not everything needs to be modeled in every language. Basically, you model to the point where the cost/benefit works out, but go no further. In Smalltalk, the cost of modeling things is designed to be so low, almost everything is an object. So of course, the cost/benefit in different environments can be drastically different, and in many, modeling everything can be a waste.

platz
But, what do you think of the specific points that were made in the video (not the title)? Are they not worthy of discussion, since, ostensibly that is why we are here?
stcredzero
In my experience, the thing that's wrong about object-oriented programming is not the object-orientation itself, but the over-application of it.

Or the misapplication of it. If an app is really about dataflow, but programmers have tried to shoehorn in a pedantic OO model, one can often end up with lots of nouns with names that talk about How (exposing too much detail) and lots of code that serves to stick data in this cubby, with other code taking that data out, then sticking it into another cubby, ad nauseum. In that case, the relationships between the cubbyholes, the data, and the dataflow are only maintained through naming conventions, which can in turn be misapplied or neglected.

This makes following the dataflow into detective work to circumvent missed naming conventions, where it should really just be following implementers/senders/references in the standard way provided for by the language.

since a model is often looked at as a representation of real-world objects, a programmer thinking in OO is likely to stick every conceivable property and behavior around the imaginary object into the model code

This is where YAGNI comes into play. (You Ain't Gonna Need It) Never implement something unless you have empirical data to back up the need. If you implement according to imagination... well, the imagination of creative tech people is often practically unbounded. So just imagine how badly scaled the result could be.

Mar 11, 2019 · 3 points, 0 comments · submitted by lrsjng
Brian Will of “Object-Oriented Programming is Bad”[0] fame presents ‘a positive case for an alternative’, or a ‘prescription for how code should be written, rather than how it shouldn't.’

[0] https://www.youtube.com/watch?v=QM1iUe6IofM

You are implying that the causation goes like this: redux good -> so the app will be good too. And to make a case in point you are trying to make an argument that because many apps are poorly designed, everyone should use redux.

You really can't see how fundamentally broken is your argument? Really???

And you are not the only one who makes this HUGE fallacy.

All the redux/react fanboys are like you. At this point I already consider those people who make these arguments that they are just following/using redux because it's a religion for them.

Not to mention the fact that some people considers the whole uni-directional message flow a HUGE antipattern. See: https://youtu.be/QM1iUe6IofM?t=1306

Sep 22, 2018 · 2 points, 1 comments · submitted by cellularmitosis
yesenadam
Great! I can stop feeling bad about never having been into OOP at all. Sure seems like longer than 20 years..
Great to see this. I ended up writing this way after watching Brian Will's Why Object Oriented Programming is Bad [0]. Near the end he states we should be writing "procedural code" but that we should favor "pure functions". What I took away from this was that at a high level I should be able to reason about a problem procedurally but the solution should be composed of mostly pure functions.

0: https://www.youtube.com/watch?v=QM1iUe6IofM

Code should be written first and foremost for humans to understand, and incidentally for compilers to understand. https://mitpress.mit.edu/sicp/front/node3.html

If we can all agree about that then we have to ask ourselves if encapsulating data and behavior at the granularity of classes makes the most sense for human comprehension. In naive OO examples (Animal -> Cat) it does. In practice however, it's debatable (at best).

I highly recommend this video by Brian Will who does a much better job explaining this problem than I could. https://www.youtube.com/watch?v=QM1iUe6IofM

Douglas Crockford also does a good job of explaining some of the trouble with classes. https://www.youtube.com/watch?v=bo36MrBfTk4#t=28m50s

Veedrac
> In naive OO examples (Animal -> Cat) it does.

An inheritance hierarchy consists of three things: a taxonomy, behavioural inheritance and structural inheritance. The first is only useful on occasion, and the last two don't even apply to Animal → Cat; "animal" is not a behavioural constraint, and a cat certainly doesn't have a platonic ideal of an animal hidden somewhere inside its gut.

famed Youtube programmer Brian Will also dislikes OO https://www.youtube.com/watch?v=QM1iUe6IofM&t=2096s
I found this anti-oop video very persuasive. https://youtu.be/QM1iUe6IofM

He also had a couple of follow up ones.

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

tome
I'm sad you've been downvoted. I loved this video.
barking
Thanks! I've always found it unnatural to design solutions in an oop way. And any time I have done it the code always seems a lot harder to debug afterwards. At the same time I kinda always felt that my preference for procedural code reflected badly on my programming skills. To hear someone who is clearly skilled and knowledgeable argue so well in support of the way i like to program was a bit like having a weight lifted off my shoulders.
One of the video that can articulate the whole thing better than me is (https://www.youtube.com/watch?v=QM1iUe6IofM)

It was a long winded written rant. I still use OOP but its more or less glorified name spaces with functions. Today I rather work on procedural code than OOP code. It may have bugs, it may have their own little quirks but its like a old rusted vehicle that still keeps going.

Prodcedural code can also be well compartmentalized and tested.

I was also until recently quite convinced OOP was the only way to go, but I'm seeing signs everywhere that a lot of the design-problems I've met over the past few years are at least magnified by OOP.

The abstraction promised by OOP is a good thing, however very few people are able to consistently make good, reusable and maintained abstractions. To the point where it becomes a weakness rather than a strength. I don't want a billion wrapper-objects that obfuscate my code, and makes the surface area of it bigger than it has to be. Often I struggle understanding code more because of how it was separated, than because of the complexity of what it actually does.

I liked Rich Hickeys talk "Simple made Easy" [1] and "Brian Will: Why OOP is Bad" [2]

[1]: https://www.youtube.com/watch?v=rI8tNMsozo0 [2]: https://www.youtube.com/watch?v=QM1iUe6IofM

I've wasted many, many years thinking OOP is the right way to do things and just realized in 99% it's the wrong approach to develop software. In the end you always end up in a big mess of classes, dependencies. And every now and then new there are new best-practices, design patterns or solutions to fix the problems only to make it even more complex.

Please watch this video. I don't agree 100% but with most of it: https://www.youtube.com/watch?v=QM1iUe6IofM

Shorel
I learned that lesson with the transition from WordPerfect 5.1 to WP 6.0.

The new Object Oriented WP 6.0 macro language was unable to do the things I did with the 5.1 macro language (a typewriter mode for diacritics plus spell checker plus smart commas and smart spaces).

Since then, I have always been an skeptic about OOP.

Also: closures are not too different to instantiated objects, one can usually convert from one style to the other while keeping all functionality.

Dec 03, 2016 · 3 points, 1 comments · submitted by jscholes
None
None
rsendv
Clicked this mainly to feed my confirmation bias, but ended up learning something. However, really ambivalent about this subject as Ole-Johan Dahl, Kristen Nygaard, and Alan Kay are personal heroes.
There is a very interesting discussion on how to go about doing this in this video https://youtu.be/QM1iUe6IofM?t=37m41s
This was interesting: https://www.youtube.com/watch?v=QM1iUe6IofM
gravypod
I took a look at that video and it definitely does a great job laying out the problems.
vram22
Thanks for the link.

Couple of points:

- it goes into a loop for me, after a few minutes, and back to the start, or so it seems.

- I get put off by overhyped self-acclamations (if that's the right word), like: "This is the most important programming video you will ever watch" - which occurs in it.

- it even stays on that above claim, for a lot longer than it takes to read it.

Some amount of claims is fine (without that, no one might bother checking it out), but after that they should let us check out and judge for ourselves.

Edit: typo

Apr 13, 2016 · 3 points, 0 comments · submitted by barking
Apr 03, 2016 · 28 points, 2 comments · submitted by Fr0styMatt88
koder2016
Knives are bad because they can cut your fingers... Don't get me started on fire!
chillacy
The starting 2 minutes were so grandiose and sales-ey that I didn't bother watching the rest, but the author does have a blogpost explaining his viewpoints, which goes by a lot quicker than the video:

https://medium.com/@brianwill/object-oriented-programming-a-...

Mar 31, 2016 · 2 points, 0 comments · submitted by Impossible
Previous videos

Object-Oriented Programming is Bad https://www.youtube.com/watch?v=QM1iUe6IofM

Object-Oriented Programming is Embarrassing: 4 Short Examples https://www.youtube.com/watch?v=IRTfhkiAqPw

I'm watching the 'is Bad' one, and honestly, it rings too close to my experience.

Need to think about this a bit more deeply!

bitJericho
Going from 10 years of strictly procedural programming to oop I can say with certainty that for most applications oop is better hands down.
mateuszf
The other alternative is functional programming (which is usually not the same as procedural programming).
kaeluka
I think that FP is a valuable addition, but not strictly better than OOP (or procedural/imperative). I think that some problems are better expressed in FP, and some are better expressed in an imperative manner and a language should let you choose.

edit: s/think/BELIEVE/

pdkl95
That conflict between OOP and FP is the "Expression Problem". Choosing which side to use for a given problem is an important part of software design.

http://c2.com/cgi/wiki?ExpressionProblem

kaeluka
What you say is sound but, IMO, not complete. There's something more to immutability vs. mutability. They both can, for instance, describe both data bases and mathematics. But there's no doubt in my mind that mutable state is better suited for the former, and immutability for the latter. It's "stuff" vs. "knowledge" that's modelled; stuff wants to change and knowledge wants to be shared.
pmontra
In my experience there is another kind of expression problem. It's usually something like this

    "a:b:c".split(":").first # Ruby
vs

    String.split("a:b:c", ":") |> List.first # Elixir
The length of the two statements is telling. Luckily Elixir has the |> and I don't have to write

    List.first(String.split("a:b:c", ":"))
OO is generally more convenient to read. It's also more convenient to think into, even when I was young and I looked at C and Lisp without much priming from previous experiences.

Functional has other advantages. I quote Joe Armstrong on that: [with OO] "You wanted a banana but what you got was a gorilla holding the banana and the entire jungle." That wasn't much different with plain C though, which could do structs and be somewhat object oriented too if you coded in the right way. And you could end up with a jungle of functions as soon as you write enough modules that need each other.

koloron
IMO, the difference in readability has little to do with the difference between OOP and FP. What's important is the expressiveness of the language.

So Ruby can be very easy to read because you can simply keep appending methods to the right.

In Haskell you can do the same, only you'll prepend functions on the left, so you end up reading expressions from right to left:

    (intercalate ", " . map show . Map.elems) myMap
What I find really hard to read, are expressions where the direction of the data flow changes, something that often happens to me in Java:

    Streams.takeWhile(list.stream().map(e -> f(e)), e -> e.isNeeded())
deadowl
Three completely unrelated things I guess.

1. Expressiveness is important? Expressiveness is why I don't like Perl.

2. You can certainly implement patterns analogous to OO in functional programming with closures and first-class functions.

3. Reading in the order of execution via chaining is definitely a lot more intuitive than reading from the inside out or right to left.

enqk
Don't you think this could just be attributed to you having gained experience?

I look at my code from 10 years ago and it is written with objects and late dispatch as main modeling tool and that code is terrible.

lucasnemeth
The 'Bad' one is all about personal opinions, no real arguments beside a bunch of information already well-know about oop and that has been discussed by years. And honestly, it looks like a iluminatti conspirancy video, with the boring narration, the sensationalist tone, the black screen. ugh.
spuz
I think you're being dismissive. Where else can I read about the arguments Brian makes in the video? I've struggled to find supporting material.
lucasnemeth
You can read Peter Wegner's Concepts and Paradigms of Object-Oriented Programming (1990), to get a deep discussion of all the concepts he speaks about oop. He is not criticizing oop, but doing an analysis compared to procedural programming. (And defending why OOP can be useful, but with no sensationalism) And he even predicts that paradigms based in concurrency will be the next buzzword after oop. If you read most of the discussions that happened in those early years of OOP adoption, you'll see a lot of the things he's pointing out has being already argued. They just were done in texts, not videos, and weren't so incendiary.
zby
Why is it all videos?

Text is so much better for evaluating arguments. When reading you can spend variable time on different parts to skim the obvious and go deep into the more difficult stuff, you can random access it later to refresh your memory, you can quote it.

Videos are probably only better in persuading people - but that requires that they watch them (and maybe get some stockholm syndrome after wasting so much time :).

bitwize
Because this is how millennials convey developer information now that they have cellphones and GoPros. Instead of essays they have videos. Instead of rationales they have footage of their talks. Instead of introductory documentation they have screencasts.

Get used to it.

Someone
I doubt I will. There are cases where videos beat textual presentations (I think https://www.youtube.com/watch?v=a9xAKttWgP4, the video about programming Conway's game of life in APL is an example) but they are very rare, and even if a few more years or decades of AI research produce a search engine that can be used to find videos answering questions I have, watching a few of the top 10 videos to apply the final human filter will still be slower than opening the top 10 search results now is.

Visually scanning well-written prose that is laid out correctly (easily recognized headers with good content, good paragraph layout) IMHO is way faster than finding the meat in well-written presentations that are presented and recorded properly.

spuz
It's not all videos. See Brian's article about OO here:

https://medium.com/@brianwill/object-oriented-programming-a-...

and the HN discussion here:

https://news.ycombinator.com/item?id=10933330

zby
Thanks for the links.

Still apparently the whole argument is only in video:

>>> [Edit: I’ve greatly expanded on these ideas in a 45 min. video.]

Mar 19, 2016 · DrScump on Inheritance Is Terrible
Perhaps the Brian Will anti-OO videos provide more useful examples:

https://www.youtube.com/watch?v=QM1iUe6IofM "Object-Oriented Programming is Bad"

https://www.youtube.com/watch?v=IRTfhkiAqPw "Object-Oriented Programming is Embarrassing: 4 Short Examples"

Brian Will says that that whole OOP concept is bad (not to say about C++ which is OOP in the ugly way): https://www.youtube.com/watch?v=QM1iUe6IofM
Feb 14, 2016 · 10 points, 0 comments · submitted by abhas9
I haven't programmed in C, but my view comes from this video: https://www.youtube.com/watch?v=QM1iUe6IofM&feature=youtu.be...

What would be the C equivalent of:

    (let ((last-response))
      (defun get-response ()
        (print last-response)
        (setf last-response (read)))) 
    
    (print (get-response))
    (print (get-response))
Notice that no other function can use last-response. It only exists for get-response, but it exists outside the scope of get-response. Does C have this?
dllthomas
As used here, there's two ways you can do this in C.

Since the variable in question is only used in one function, you could declare the variable static to that function. It takes some care to make this reentrant, but that's possibly the case in lisp as well.

To share between multiple top-level functions, you can only limit scope to the individual file.

The bigger thing C can't do that lisp can here is defining new functions in arbitrary places. In C variants where you can define local functions, you can indeed capture variables in local scope. And within a function, you can limit scope by creating a new block:

    int test() {
        int foo = 7;

        {
            int foo = 9;
        }

        return foo; // returns 7
    }

Even in those C variants, you can't place a new function in global scope from within a function.
such_a_casual
I did not know C had static variables at the function level (thank you for pointing this out), but static variables are not the same thing as what I'm thinking of when I say "explicit scoping". It would basically be like writing curly braces for variable declarations the same way one does with function definitions. Because lisp has this it's trivial to extend the scope of the variable to cover multiple functions:

    (let ((x))
      (defun func1 ())
      (defun func2 ()))

This is what I mean when I say explicit scoping. And it means that the reader/debugger/maintainer knows that this variable only exists for these functions. A static variable's scope is implied by the scope of whatever it's defined in (not sure if that's limited to functions in C), in this case X exists outside of C and has it's own scope, not just it's own extent.
dllthomas
"Because lisp has this it's trivial to extend the scope of the variable to cover multiple functions:"

Yes, I mentioned that static variables in a function would not extend to multiple functions.

You can share a variable between a restricted set of top level functions by grouping those functions in a single object file that does not expose the variable in question.

I think my only objection is that your phrasing implied what's different is the explicitness of the scoping, when it's actually the flexibility of how functions can be defined (unsurprising, from a lisp).

such_a_casual
I used the word explicit because I was thinking something along the lines of: the scope in lisp is explicitly defined with parentheses (). Where as something like a static variable (or pretty much any variable that's defined in Algol like languages) has implicit scoping, it's implied that it shares the same scope as the scope it's defined in (or some other implication like C#'s public). I'll have to find a better way to word it because you're right. Thank you for the discussion.
Feb 09, 2016 · 3 points, 2 comments · submitted by jtwebman
chrisblackwell
This video seems to only focus on the negative areas of OOP. There are of course some wide benefits.

I think the truth is in the middle somewhere. As always, pick the right tool for the job.

jtwebman
You should have watch it all. He covers all.
Feb 01, 2016 · 4 points, 1 comments · submitted by whistlerbrk
lispm
The USE construct is trivial in Lisp:

    (defmacro use ((&rest vars) &body body)
      `(block nil
         (let ,(mapcar (lambda (sym) (list sym sym)) vars)
           ,@body)))
Example:

    (defun foo (x y)
      (+ (use (x)
           (incf x 10)
           (return (+ x y)))
         (use (y)
           (incf y 12)
           (return (+ x y)))))
-> 28
Jan 21, 2016 · 3 points, 0 comments · submitted by jergason
Jan 19, 2016 · 3 points, 0 comments · submitted by thomasvarney723
Jan 19, 2016 · 26 points, 8 comments · submitted by jbeja
kristianp
Related non-video content:

https://medium.com/@brianwill/object-oriented-programming-a-...

kristianp
I found the video was well presented, and the speaker spoke very well. The argument starts at around 18m20s after some background.

Having recently started working on an ASP.net MVC project, I'm in agreement with this video that there has to be a better way to create applications. So many classes and so many services, controllers, dtos (1) and interfaces have to be written. I think the video is railing against the Java and c# style where everything has to be a class, and I agree with that. Comparing Rails with the GoFness (2) of a Java or c# web application, you can see that there are better abstractions that can be used than just creating structures of objects to solve every problem. Programming languages or tools that allow more dynamic constructs or higher level static constructs or code generation are better than just making the developer build many classes to fit into an OO framework.

I know this kind of thing has been written before, but I wanted to write in support of this video's viewpoint.

(1) Hence this kind of thing http://stackoverflow.com/questions/10313128/java-generics-co... .

(2) GoFNess - Design Patterns: Elements of Reusable Object-Oriented Software is a software engineering book. The authors are often referred to as the Gang of Four (GoF).

EvanPlaice
Wow. So many aspects that I've attempted (and failed) to communicate to OOP devs in a clear, understandable presentation format.

I've been working with Angular2 a lot lately and it's has been painfully obvious how much effort they've put in to make the framework appeal to devs with an OOP mindset.

God object? Yep, they use a directed acyclic graph for to manage dirty checking. Global state management via singletons? See services. Factory pattern? See providers. Static typing with type coercion, interfaces, and class based inheritance? See Typescript. Etc...

They have effectively reimplemented every single common design pattern used in OOP, in Javascript. A language that fundamentally doesn't require OOP patterns to provide the same degree of flexibility and functionality.

It gets really 'weird' when they encounter aspects that can't effectively be defined using OOP alone, such as async data binding. Instead they use functional programming patterns such as observables/promises.

Personally, I prefer to write NG2 code in ES6. Types in Javascript are nothing more than window dressing to make the transition less painful for OOP devs and enable better autocompletion support in IDEs.

In practice, type checking during runtime will have to be disabled because it causes a significant negative impact on performance.

TBH. It feels kinda 'dirty'. Like I'm some OOP addict (ie C# dev in the past) who is dabbling with old habits.

garyclarke27
I agree the headline is a bit "over the top" but it does grab you're attention. The Video is actually extremely well done and very interesting - odd to me how some commentators feel justified to publish a disparaging opinion on this, when they haven't botyered to actually watch it! I've never been that enamoured with the whole oop religion, but was always puzzeled as to how come it's beeen so succesful, if it's not that great? This video finally solves that puzzle for me with a very compelling explanation for this. I was intrigued by the presenter so had a look at some of his othe work, the guy is a bone fide programming genius, his knowledge is incredibly vast, this for me supports his credibility and his opinions.
stevenalowe
Ridiculous clickbait. 'the most important programming video you will ever watch', 'An explanation of why you should favor procedural programming over Object-Oriented Programming (OOP).' Yeah right. As if the last 30+ years of software development never happened.
PhilWright
The title of the post is patent nonsense, so much so that I cannot even be bothered to watch the linked video.

I have written software for almost 20 years that is OO based. I have worked on lots of successful projects that made companies lots of money and served countless end users well. Sure, there have been failed projects along the way as well.

One thing you realise after many years in the industry is that the quality of the developers on a team is more important than the paradigm they are using. I've worked with poor developers that would have written crap software in whatever language/paradigm/environment they used. I have also met some amazing developers that could develop great software in the worst language/environment imaginable.

So saying that OO is intrinsically bad is simple nonsense and frankly childish.

jbeja
I feel like a fool sledgehammer world entities into hierarchical taxonomies of interacting objects and coupling behavior with data.
None
None
EvanPlaice
That's perfectly fine. Nobody is forcing you to not use OOP.

The video just outlines the fundamental weaknesses of using OOP as the end-all-be-all solution to managing encapsulation. Namely, that it creates as many (if not more) problems than it's superficially purported to solve.

IMHO, OOP is a useful design pattern for some specific classes of problems. Treating it as a cure-all ideology is self-defeating.

There's a huge disconnect between creating large applications using OOP and maintaining them over the long-term. In the latter case, abstractions that get baked into an OOP-only architecture will eventually start to leak in dangerous and unexpected ways as the needs of business change over time. Short-term savings in the form of strict adherence to DRY and SRP can (and will) eventually accrue as technical debt over time.

Common conventions such as design patterns, DI, and TDD minimize the negative impact but they're indicative of a bigger problem.

With that said. I agree, the title is dumb and clearly detracts from the underlying message.

Jan 19, 2016 · 15 points, 5 comments · submitted by delan
humbleMouse
Just use the good parts of OOP and forget about inheritance brah.
EvanPlaice
Favor interfaces and composition instead brosef.
humbleMouse
Don't use paramatized types brotha.
JosepRinaldi
so which procedural language should we be using? still waiting to here a recommendation? best recommendation he offers is a combination of object-oriented and functional ?!

title should be rewritten OOP is good. with some small changes - prefer stateless instead of stateful - prefer aggregation of objects over inheritance - prefer functional first

I guess no would see the video if he had a reasonable title that made sense.

rswier
Write in C

https://www.youtube.com/watch?v=H4YRPdRXKFs

HN Theater is an independent project and is not operated by Y Combinator or any of the video hosting platforms linked to on this site.
~ yaj@
;laksdfhjdhksalkfj more things
yahnd.com ~ Privacy Policy ~
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.