Object-Oriented Programming is Garbage: 3800 SLOC example

preview_player
Показать описание

Рекомендации по теме
Комментарии
Автор

Next video's title will be: Object-oriented programming is literally hitler.

Czarmzy
Автор

This guy /actually/ has standards and sticks to them when they make sense, and not just because 'education' forced them into popularity. I highly respect that.

wtfppl
Автор

I started doing software in the 80's, creating ERP systems for small organizations. This was before: big networks, object oriented programming, SQL, and widget/event centered user interfaces. My productivity then was DOUBLE or TRIPLE what it is now using modern tools. It drove me nuts dealing with one fad after another, each one slowing productivity and exploding complexity. The popular cloud based DBMS I work with with now feels like a ship with a thousand leaks. Nobody seems to get that Simplicity is the golden rule of software.

marknomark
Автор

BREAKING NEWS from year 2023: OOP still sucks badly, but they still use it.

michimarz
Автор

To me the underlying problem is the conflict between theorists and those who actually need to create and maintain practical, working code. Theorists become more and more obsessed with their paradigms and adopt a "more object-oriented than thou" or "more functional than thou" view. But in real life there should only be one test: does using object-oriented design in your code make it simpler, clearer and cleaner? Then use it. If another program would be simpler, clearer and cleaner by using a procedural design, then use that. And if neither of those paradigms work then use a combination of the two (or make your own). Bottom-line: don't let any programming paradigm work against you in your code.

rajsrivastava
Автор

Came for bashing OOP, stayed for NES emulation code.

TheMRJewfro
Автор

50:10 "In fact when I think about the complexity of a function, I don't really think so much of it in terms of cyclomatic complexity, of how deeply you're nesting loops and branches and so forth (I mean that is a concern), but for me the real measure of complexity is, well how many variables do I have to keep track of."


Not sure how much of a fan you are of code metrics, but that sounds like an interesting idea for a complexity metric. How large is the state space, based on number of parameters, variables and references to globals.

ManuelBTC
Автор

The Fred Brooks quote reminds me of Linus' saying: "bad programmers think about the code, good programmers think about data structures."

JethroYSCao
Автор

In haskell, you can put a "where" word after a function defunition and there you can describe all subfunctions (and each of them can have the "where"-block itself). They will retain visibility on the parameters of the root function.

slowpnir
Автор

Not only you've made very good points in your previous videos, but also provided this example, kudos for this.

I think most of the problems come from adhering too strictly to any particular paradigm, but I agree with the notion that imperative happens to be the one that gives the programmer the least amount of headache.

oxdeadbeef
Автор

IMO the problem with Object-oriented is when you let it dictate your design and plan all of your classes before you've written your first line of code. Some languages force you to make a class first so you're already starting with a disadvantage.

KD-rhcr
Автор

Here's my view on some of the things you said / showed:

a) Your criticisms of the Console pointer in CPU etc. are a bit... odd. Its not uncommon to have bidirectional child<->parent relations. I don't see the problem in this case, especially since a real CPU is also connected to the rest of the system... otherwise it couldn't much of anything. Okay, they could have chosen to pass in the current state of the memory each loop, I guess, but that would be even farther away from the real situation. What is especially odd to me about your criticism of this point: It seems you especially dislike OO design that sticks to principles just for the sake of it. I agree with that. Yet, here you criticise this reference without any real reason except for principle. It's handy to give the CPU a pointer to the console, because then the CPU can easily access the memory. There's nothing confusing about that. Sure, it could have been a pointer to the memory, keeping it a bit cleaner... but that's about it.

b) Private, nested functions: I never saw the benefit of these. You still have the same work to do. Define a complete function with a decent name and call it somewhere. The only difference, really, is you choose to put it at the beginning of the parent function and assume you'll never have to call that function from somewhere else. So what? It would be just as readable if these functions were defined on their own just above the parent function. On top of that, you wouldn't have to change your code if you realized later on that, contrary to your initial belief, you now have need of that function somewhere else.
More important than were a function is defined is how intuitively understandable its purpose is.

c) I really don't see how inlining a lot of functions and creating longer functions helps readability.
One example would be your main loop:
I would much prefer a main method that basically gives an outline of what the program is doing by calling other functions in a specific order.
- InitialiseAudio(); InitialiseGL(); as separate functions I only need to look at if I actually care what's happening there. It's a really "boring" part of any program, as it doesn't add any understanding of its purpose. It's housekeeping. I don't put my vacuum cleaner next to my couch because I don't need to see it all the time to know I use it to keep my place clean.
- MenuView / GameView taking care of their loop iterations on their own, for example, would clean up that main loop a lot... I really don't have to fully understand what each view does to get the big picture of the main loop. And if I do need to see what they do, I can easily check it out. I like taking a "hierarchical" approach to understanding a program.

Doing things like this, your main method would probably crumble to less than 100 lines of code, would still contain the essence of what it's supposed to be and would be free of stuff that, to me, is irrelevant detail for my understanding of the main loop. I could then go and check out GameView and MenuView... since they tackle two separate issues: Displaying a game and displaying the menu.
I could go on, but perhaps you understand my point of view: Inlining functions just for the sake of it doesn't help readability and understanding for me. As you yourself said in another video: When we try and understand the human body, we don't first look at microbiology. We look at the organs. What your main loop here is doing is saying "there is a lung in your body and here is its microbiology" before telling me about how the lung fits together with the rest of the organs.


After watching this and your other two videos about how terrible OOP is, I have to say: You don't really make a strong point. Sure, you showed some really terrible OOP examples. Here, you showed a not so terrible example of OOP and turned it into a, IMO, not so great example of procedural programming.
I would have liked your videos a lot more if you hadn't started with that "most important programming video you'll ever watch" bit only to continue without saying anything new:
Doing something bad is bad.

Clairvoyant
Автор

For me, OOP dogma really hindered my early years of programming. It made me hate programming and hate any code that I wrote and see it as utter dogshit, even if there was nothing technically wrong. I wasted so much time on questions such as... What work should be done in this class constructor? Should I split this class into two pieces? Should I move this piece of data from class X to class Y? Do these classes make sense philosophically? Should this function be a member function of class X or class Y? Should this member variable be public or private? Should it be const? Should it be accessed with getters and setters? Should I write const versions of my class member functions? Should helper functions be private? How do I write tests for private member functions?
Then there were further questions like: should my functions be only 5 lines long? Should my classes have only 5 members?
For the code I was writing none of this mattered! I should have been writing procedural code, and should have only started thinking about these questions if I wanted to wrap a public API around my code.

danielgould
Автор

I've been doing procedural PHP programming for 25 years. Never understood the need for pages of getters and setters and abstractions - when you can just write straight A to B fuctions with half the code. Love these videos.

DjSadhu
Автор

I know this is never gonna be seen by anyone, but I had a bit of a revelation while watching this so I'm gonna drop it here. I realized a big difference between people like Brian with a real distaste for OO, and people who absolutely fucking love OO. Brian's priority is to write "straightforward" code so someone coming behind him can easily understand the entire code base. A lot of these pure OO people do not care about that. Their priority isn't to have the entire system be digestable, but structure the whole thing in such a way that any idiot can come behind them, only worry about some small corner of the code, and get something working in that little sandbox. Those two very different priorities are going to lead to very different styles

jeffreyhymas
Автор

The reason for the "Memory" pointer pointing to the "Console" -- at least in my opinion without having looked at the code -- is that the 6502 uses memory mapped IO and the "Console" structure actually represents the physical hardware connected to the CPU via the memory/IO bus . Lots of NES emulators, or 8 bit console emulators in general were conceptualized this way (I know this to be true as I've done a lot of work with NES emulation). In other words, the "Console" structure really represents the physical interconnects between the hardware and is used to facilitate data transfer between those components the same as the memory/IO traces on the mainboard.

raiauge
Автор

But what about the issue of job security? If your code is easily readable by outsiders, you have no assurances you wont be replaced.

judgeomega
Автор

I work in the automotive industry on safety critical software (e.g. braking controller)
We use C language and it is horrible. Is it horrible because C is a bad language? No.
It is horrible because unexperienced people (e.g. kids just out of school) write the code.
No time to think about good software design, no time for refactoring etc. (Sometimes the existing bad code is used as excuse to write even worse code.)
But this seems to be the "industry standard", because those kids are so cheap and don't complain all the time...
I don't think OO is bad, if used wisely. But when unexperienced, writing OO code usually ends up worse than writing procedural code...

Webfra
Автор

47:00 This is a fantastic point. Atomised code is misleading because it looks like it is more meaningful, more thought-out and more general than it actually is. This is especially true in OOP, because if you write a small class, according to OOP, the class is meant to have responsibility of its own. It becomes an entity in itself, with a nice name and an intuitive description of its responsibilities. This is misleading because the class may only be used once and its methods may only be designed to work correctly in one particular case. The code is dissatisfying because it feels incomplete, and it becomes tempting to over-engineer the code so that the class is more robust and lives up to its name.

danielgould
Автор

Agree with most of this, but not the inlining of of all of the functions. I like code to read like plain english. Inlining all those functions reduceds testability and navigability, which are both extremely important. It also increases indentation, which can make code more difficult to comprehend.

howardjohnprice
visit shbcf.ru