Sasecurity Wiki
Advertisement

comment 1[]

Those yelling "WHAT ABOUT BIG PROJECTS": An outspoken critic of OOP is Jonathan Blow. Here are two big projects he's done. You ever heard of Braid? It's a critically acclaimed video game from 2008 about time travel, which as you'd expect is pretty technically complicated, since it must efficiently store the state of every entity at every frame. 90 thousand lines of C++ code, all of them procedural. No STL. Runs perfectly on PC, Xbox 360 and PS3. You ever heard of The Witness? It's a critically acclaimed video game from 2016 about exploring an abandoned island, and it's got a triple-A-scope open world with a draw distance of infinity. 200 thousand lines of C++ code, all of them procedural. No STL. Runs perfectly on PC, Mac, PS4 Pro, and Xbox One. Now, tell me which OO software is more robust than these games.

virtual functions[]

Your rant about floating point precision, aside from being strange, didn't actually address the robustness of the time travel feature. A modular object system that lets you add features and behaviours without changing the central structure of the code is bad. It may seem to increase development speed, but nobody has seriously demonstrated that to be true. From a design/quality standpoint, if you're inserting a feature into something like a game without considering the "cross-cutting concerns", you're basically doing a tack-on job. That means the feature is likely either bad, unnecessary, or doomed to yield a bad user experience. You are obligated to consider every interaction between components or else your software is incomplete. Nobody here encouraged copypaste programming, although the crusade against any and all code duplication is part of the reason why the world's software is terrible. Static analysis is good. Dynamic analysis is good, but only during development of course. Unit testing is garbage. Ignoring the fact that virtual functions aren't necessary or useful for any purpose, they eat some indeterminate amount of space from the beginning of any structure that uses them, meaning the structure's memory layout can no longer be optimized.

Calling a virtual function risks a cache(cache event) miss dereferencing the object pointer, another dereferencing the vtable pointer, and a third dereferencing the function pointer. This gives virtual methods a minimum overhead of maybe ~3 cycles and maximum overhead of 600 cycles or more, not adjusted for branch misprediction. Iterating over a collection of objects with virtual methods will thrash the icache unless you sort by type. That means your objects must store their own type, at which point you could be using a switch. Philosophically, virtual functions are bad because they mandate that they remain abstract. Their implementation is opaque to the programmer, but experience with the real world shows that you actually have to care about the implementation of things. They are better done in userland than as a language feature, even considering compiler optimizations.

2[]

You talk a lot, you make 0 good point. Why are you arguing with us? You mixed functional programming and oop... Are you really a programmer? I'm really starting to doubt it. Especially what you said about memory. Not only you do not agree with the thing i told you you were very wrong about, but you seem to be in constant confirmation bias. You're like one of my friend who can't be wrong and want to argue but show no evidence, no example and brag about what he preach. Saying Functional doesn't contradict OOP is a joke. Poor attempt by your side. Saying Functionnal programming isn't possible in c++ is also a joke. I've yet to see OOP good side with exemple. That's my point. I see none. Most of the OOP stuff is optimised in assembly after to get it right. One of my friend work at Ubisoft and is one of the guy who does optimizing and it's pretty much a mess. He would love if people would stop programming in oop because it would made his job shorter and easier. YOu seem to not understand WHY C is still around and still strongly useful. Things that need critical stability like in hospitals or in military are made in C not, c++. Okay i'm wasting my time on you XD! Poor being.

3[]

The thing is, OOP is ineffective. The implementation is fundamentally hash maps with instantiated context-sensitive namespacing. And that's perfectly fine if that's all you use it for. But the second you start using objects to dictate control flow, you start building a babylon tower of interface spaghetti that no single man can fully understand in it's entirety.

My main issue with OOP is not just obfuscation of code but actual runtime performance decreases because of the heavy focus on the code modeling the real world instead of focusing on how data is actually being transformed. I don't care if my object hierarchy is laid out according to my mental model of the world if I'm constantly missing the cache because of it. OOP is terrible for games, for 2 reasons OOP is hard to paralelize and OOP is prone to cache misses also every major game till psx era was mostly written in assembly, not even C, heck even till ps3/360 era lot of assembly is used so fine control over memory can achieved

OOP fundamentally has 2 out of 3 of the right ideas (encapsulation and polymorphism); but how it executes them is terrible, and in the case of classical OOP, it pairs with inheritance over composition.

4[]

William Baric Unnatural? Our lives are made up of objects thought of in the way programming thinks of it. When I say "car" to someone, an image comes up, the know it has an engine and wheels and turns and speeds up. OOP takes advantage of this fact while procedural programming has no concept of a "car" or any other object. In procedural programming, there is no "car", but there does exist every element of that car, be it speed or state or color or whatever. OOP consolidates those into a template that all cars can be built on. It's a ridiculous statement to say OOP is unnatural, a kid will know what a "car" is before they know what a 2005 Mazda Miata is.

This comment is typical of not grasping that that object oriented programming, oop, is Struct stuffed procedural programming, where all the functions inside the struct itself as their first parameter(restricted or encapsulated global).

William Barric replies to DrMantisToboggan: ".... Objects don't act, they are acted upon. A circle doesn't draw itself, I draw a circle. That's why Object programming is completely unnatural....."

Which, stripping out the object metaphor is saying: .... procedural input to output mapping don't act..... a category mistake has ruined computer science. In the real world, indeed rocks don't act, they are acted upon. There isn't a rock inside a computer.

5[]

Okay, Which one is more readable (also testing how far google went implementing markdown)?

   bool carengine1poweredon=true;
   bool carengine2poweredon=true;
   Vector2 carposition1 = {3,4};
   Vector2 carposition2 = {15,64};  //struct {int x; int y;}
   int carspeed1=60; //mph
   int carspeed2=59; //mph
   int cardirection1=35; //degrees
   int cardirection2=55; //degrees
   if (carengine1poweredon) {
       movecar(carspeed1,carposition1,cardirection1);
   }
   if (carengine2poweredon) {
       movecar(carspeed2,carposition2,cardirection2);
   }

or this (OOP):

   car Car1=new car(new Vector2(3,4),60,35); //position,speed,direction
   car Car2=new car(new Vector2(15,64),59,55); //position,speed,direction
   Car1.powerEngine(true);
   Car2.powerEngine(true);
   Car1.drive(); //drive() checks automatically whether or not engine is powered on and moves the car accordingly.
   Car2.drive(); //drive() checks automatically whether or not engine is powered on and moves the car accordingly.
The second one would be understand by even a young child, while first can barely be understood by even moderately experienced programmers. Of course, OOP is not a one size fits all solution and it will never be. It mostly has it uses where you can classify things into logical objects - labels, buttons, checkboxes, entities in a videogame, people being on a payroll at your company.

That right there in the OP's comment is why OOP is ineffective. If you're working on a real life product it's unlikely you will have just one or two cars, you'll probably have lots of cross cutting concerns, and then the car class will need a ton of other classes (engine, tires, wiper fluid, ignition key) each with some extra class dependencies of their own. And then you need to start connecting the engine class with the fuel tank class with the tire class with physics engine class. You will end up with a horribly brittle class hierarchy that's painful to maintain and really hard to understand. But hey, you can write car.drive() that does some stuff automatically behind your back, with lots of possibly-bug-producing side effects. Great success. Not to say that OP's procedural code is better, but when you write large programs you can write procedural code that's easier to maintain because there aren't so many dependencies to think of (if you write the code properly, that is, because you can write really bad procedural code as well).

6[]

Brilliant analysis. Brian Will has articulated what I've felt for decades about OOP but could not wrap my arms around. Thank you!! On the particular KIND of bugs that we see in today's applications: The kind of bugs that OOP might produce vs the kind of bugs that procedural programming might produce have distinct characteristics. Take the case of Spellcheck as it operates erratically in certain versions of Word. Usually it sails right past one of my hyphenated words (in which I always use the hard hyphen), but if the moon is gibbous, then it chokes on the hyphenated word, and halts the Spellcheck routine to ask, "Resume?" That kind of behavior (linked to phases of the moon or to whether a fairy sneezed a prime number of times in heaven) is inconceivable for an application that was written procedurally, but it is just what one would expect from OOP where the actual lines of logic are subordinated and buried beneath layers of icky, half-baked doctrinaire. (As for the negative comments on this video, they smack of vested interest and group-think -- a reluctance to admit that one has spent so many years of his/her life, not to mention mucho dinero, on something that turns out to be ugly and bogus as a programming philosophy. Ken Kopelson's comment, with "this guy didn't learn properly," I found particularly offensive; Ken claims to have 'watched the video' but he couldn't have for his remark is a non sequitur.)

7[]

OOP does not need encapsulation. You can create an object-oriented language without a private keyword and purely use objects for data/function grouping. - In your object graph diagram thing, the whole idea is that each object manages its own state and there's no need for such a "god" object. External objects should never be able to poke the current object's state directly (hence why OOP almost always does come with encapsulation.) Of course any real program will need some sort of overall control (otherwise objects just sit there not even being instantiated) but that applies equally whether you use int main() or public static final Main(). - There's a huge divide between "in practice" and "in theory." You kind of touch on that here and there but the bottom line is that any paradigm will end up with people doing something stupid. Make pure functional programming the standard? You'll get people marking every single routine as a monad. Make procedural programming the standard? You'll get people that just toss everything into global variables. Not because that's the right way to do things, but because the possiblity exists (by necessity) and as long as it exists, someone will eventually decide to abuse the system. I don't know about the Java world but in C#, rarely do you see a (good) third party library with significant amounts of factories and managers and crap like that. Those kind of over-complicated designs are generally considered bad even in the OOP world (and we hear about them mostly in the context of "can you believe they did something this dumb?") I'm not saying OOP is a panacea.. I agree that its got its problems. All I'm saying is that any other methods will its problems as well. As the old saying goes, there is no silver bullet.

8[]

Not sure I agree with all of the premises in this video. Most of the issues are due to poor programming, not necessarily the language. In most systems I've worked on, you have two types of classes - "data" and "logic". One simply encapsulates the data you wish to work with and has associated getters/setters (and maybe a few utility methods), the other I guess you could call your procedural class which manipulates the data objects. I've seen these procedural classes called various things - business objects, technique classes, even managers as he states in the video. These classes typically do not have state. Nothing inherently wrong with this methodology, just comes down to properly structuring things to reduce complexity and reduce the probability of duplicate code/reinventing the wheel. Java, as it currently exists, doesn't have true encapsulation. Returned objects can be manipulated, giving the caller an indirect way to manipulate the state of another object. I agree to a certain degree with not breaking up functions simply due to lines of code. I call it bread crumb programming since you have to follow the trail of crumbs to figure out what is going on. I do not personally prefer inline functions, since it reduces readability. IMO if it's never going to be called in more than one place, it shouldn't be a separate function. I've worked with almost every type of language. Is OO perfect? No. But I'll take it over pure procedural any day.

9[]

think this video takes a very narrow view of Object-Oriented Programming. OOP as taught in a university or online, is not what it was originally when it was invented.

19:32 "For object A to send a message to object B, A must hold a private reference to B" - Not true. Another way to approach this is to have object A emit an event that object B is listening for. Or for there to be some kind of lookup registry that contains the names of objects that are interesting to object A. Even if it did have a reference, what's wrong with that? The state is not actually shared, because objects B and C cannot modify the state themselves. In fact, they would not even be aware that there is any state. They are just passing messages which inform object A.

20:44 "You can impose rules through the accessor methods like..." - Well there's your problem. It's true that setter/getter methods make encapsulation almost pointless, but who says that's part of object oriented programming? You mean just because it's so common in Java, etc? I'd argue that getters/setters defeat the purpose of message passing, where the idea is that the object should be responsible for its own state. If you can reach in and play with that state, albeit with minor limitations, then how are you really encapsulating anything? Think about if a process could reach into the data of another process.

What would be the point of distinct processes then? True OO is better represented by Alan Kay, Dan Ingalls, David Ungar, etc, as in the following videos. https://www.youtube.com/watch?v=Ao9W93OxQ7U and https://www.youtube.com/watch?v=QjJaFG63Hlo

10[]

This guy is responding to the INSANELY abused OOP paradigm that makes so much of our daily lives suck. He's right on a lot of it. Most class definitions I've read on the job as a professional developer are absolute garbage. And the perfectly engineered examples academics love so much are so different from anything your boss would ever ask of you are worse than useless. My big objection to his talk is about relying on comments to understand code logic. Dude, come on! Have you ever read a comment that was actually current? Also this problem is not specific to OOP. The bigger problem I see in the industry is people's unwillingness to admit they don't understand some ridiculous nested class hierarchy because they're afraid of looking stupid at work. Then the original author(s) of said hierarchy use a lot of bullshitty buzzwords and half truths to justify the complexity. I find that if you can't summarize object behavior in a simple way you're most likely lying to me.

11[]

This is actually a very interesting analysis of programming techniques. I have a couple of definitions of OOP, OOP(S) and HOP (hardware oriented programming) and while there is a touch of humour here, processors generally talk in opcodes. To make opcodes somewhat more manageable, the opcodes are assigned mnemonics and most hardware (processors) have their own instruction sets which generally perform similar operations in the hardware. I am using a Windows model here as it is generally the most used operating system around the world (warts and all). Above mnemonics you have the massive and often inconsistent API functions which in relation to mnemonic coding, are far higher level. With the end of Moore's law, processors are not getting all that much faster, the increase in core count and the availability of 64 bit processing have given some more room for improvement but the fundamental problem is that demand for computing power is not being matched by processor power and the only realistic solution is to produce more efficient code. I am still fascinated with the size of much of the commercial software available where 80 to 100 meg is common and some are far larger, the direct consequence of multi-layered very high level code. It needs to be remembered that man was put on the moon with software that measured in KILObytes, not megabytes and it was reliable in most instances. With a background in assembler, basic and C, I agree with the view that if you want the speed and efficiency of past software in its own context, you write hardware based procedural code.

12[]

've watched the full video now and I can't endorse it.. He lists (and I'm sure he'll hate this term) anti-patterns of OO usage. They happen more often when the developer has just learned the principles. A great analogy is teaching students about normalising data in a database to 3rd or 4th normal form results in overly normalised databases. The techniques taught are good, but it's easy to apply them badly. His view of what constitutes OO is accurate I guess, but he doesn't discuss the fact that OO languages are becoming more functional and more functional languages are becoming more OO. His history lesson is sort of accurate but I don't think Javascript came up once. That's a weird omission as his methodology actually sounds like old fashioned Javascript. His solution is long procedures with lots of parameters. He does mention functions should be pure if possible, that's good, but beyond that it was red flag after red flag. Things like "Use a parameter instead of a global variable". This is good advice, but it's true of OO languages too. It's not perfect advice, if a function is pure, does it could be global or static, and if it's pure it can be memoised. that look up table could happily be global. He doesn't like it when people take a long method and extract out segments, so instead of 1000 lines of code you have 10 lines which say things like "Put cereal in bowl", "Pour milk into bowl", "Eat". He argues that you can leave them all in one method and simply comment each block. Sure you can, but this is preference rather than dogma and it applies to his solution and to OO. Finally he starts talking about scoping variables locally to sections of the giant procedure he's writing. Which is just another way of saying "This is a separate procedure". The whole thrust of his argument seems to be that he's happier reading code if it conforms to his style. The absurd thing is, I've spent a lot of my programming life doing procedural programming and even back then, if he skipped all the OO stuff and just presented his solution, I still would not have been convinced.

13[]

Your diatribe about object orientation/message passing holds some flaws: the idea of message passing is dependent on a naming service, where by objects can resolve other objects as targets of messages without holding direct references to them. ETA: At the end of this essay, I think I have a perfect programming language for you: SML. It favors procedural style, makes it easy to parameterize, make pure functions, and has a very powerful module system ETA2: Rust has almost the "use" feature you wish for. It is possible to define procedures (not closures, so not partaking in local state) within a procedure block. They are then only visible from within this procedure, and can be called before declaration.

14[]

OK. I'm ~21 minutes in and I'm bailing out. You are basing your argument on the definition of a "message". And the whole "you can't do this because it violates the definition" simply doesn't reflect the reality of the object oriented languages I have been using successfully for decades. Yes, OO design can be done wrong. I have seen it many times, but I believe, and I have plenty of empirical evidence to show, that it can be done successfully. Code can be shared successfully across any number of different situations. If you really think that inheritance is irrelevant, then you aren't doing it right. And State can also be maintained with objects that other objects use and refer to (breaking the rules of your "message") with great success. I'll stop there, but I could certainly go on.... Thanks for your thoughts, though.

15[]

his is one of the most bloviating and ultimately vapid pieces of crap on the subject of software development I've ever seen. Java did not succeed because it was OO: It succeeded because people were drawn to it from the promise of 'write once, run everywhere', had some major industry support, and received MAJOR HYPE in the industry, and nearly all vendors wrote Java-compatible SDKs and platforms. OO development NOTHING to do with UIs. Suggesting that is moronic. Encapsulation is bad?! Before we figured out how to make pseudo-namespace variables in JS, I'm sure you never created some little JavaScript bug that took you hours to track down because you accidentally overwrote something you weren't supposed to, due to everything being in the global namespace. I'll take 'trivial protections' any time, IF I WANT THEM. Equating over-architecture with OOP is pure rubbish. You can create MVP (minimal viable product) in OO and modify it just as quickly. The major proponents of this paradigm, the 'pragmatic programmers' were major Ruby developers. Think about that. No one is doing OOAD anymore.

Seriously. Who is? To suggest that is a thing is ridiculous. Most people using OOP don't even use more than one level of inheritance anymore. Composition over inheritance has been the recommend practice for YEARS! Separate files are BAD?! I don't think I can take this anymore. Do you even work on teams and use source control? You really want to merge some 400K line file? You are seriously amateur in these arguments. To search, we don't 'look through files' in 2018. We use the search capabilities in our tool, and object/class browsers, and...shudder...GOOGLE! For all new programmers out there: ignore this drivel. OO is not 'bad', but may not be appropriate in all cases.


Use the appropriate tool for the job. That's why in 2018 we still have dozens of languages that do things in many different ways. You need some glue between something? PowerShell it. You need some throway POC app to prove something out: use whatever you're best at. You need something that will be maintained over time by a large team: use whatever your team is best at and will meet the technical needs of your application's requirements. That could be C, Go, Python, or whatever. Finally, I hate to break it to you: you cannot write any non-trivial application out of purely 'pure functions'.

You may have a decent percentage, but all those UIs out there, and operating systems, and games require state. What rubbish. I seriously don't think the author has created any large-scale production, mission-critical application that will be maintained over a long time frame by a team of developers. This is seriously small thinking here, with an extremely closed and biased mindset.


16[]

Good video, but I have to disagree as well. You pretty much illustrated the problem I've seen in most of the code that I have reviewed and it's that people just don't think of a context of their program, they just throw classes and when the code doesn't fit, they throw in utility classes... and if the code is too large in the utility class, then throw in a UtilityUtility class. Context is what defines the encapsulation, you can't go around trying to encapsulate state and behavior out of your ass. If I've noticed something in the codebases that I've worked, there is pretty much never a well defined context. If you are dealing with loggers, you need to identify what a logger is and what is not. If you need to log to different places (file, network, database) you need to identify how does that affect your context and in which part of your context they apply. This way, you'll have a proper hierarchy that allows you to find where the code that you're looking for should be located. Thanks for presenting it this way since it inspire me.

17[]

I agree with most things and I will be trying procedural programming. But one thing that it seems like you completely forget that abstraction is a black box. You don't need to understand what is done inside, just the spec or name/doc, and if you are writing the blackbox or another implementation you don't really care what's outside, just that you follow the spec that the abstraction imposes. That's why I really like abstraction. I just read what it does and then... well it does it. Not only that but most self contained code that I write is some sort of an abstraction implementation. (in a form of a simple function interface) Now as you said when I put up walls that will need to be changed in the future then that is kidna the same in function calls as you need to change the structure and arguments of a function. To me it does not look like a fix but just a different expression of a problem that I don't think currently has a true "fix".

18[]

This sounds more an indictment of lack of design than OOP. I programmed both procedural and OOP. Having learned OOP using Smalltalk and Lisp, by the time I learned C++ and Java, I came at OOP programming very differently than those who started with the latter. Harlan Mills repeatedly demonstrated the value of mathematically proven design, yet the business call for creating a prototypes eventually overwhelmed the idea in the industry. Agile methodology further allows the programmer to really skip design and figure the whole thing out later. Early Java libraries and even MFC went a bit overboard on the use of inheritance and that started to turn programmers off to the idea. Nowadays, I see more code written with a procedural ideal, but using objects. Component frameworks like Spring and entity frameworks like Hibernate helped feed the creation of discrete objects, instead of the OOP concepts that actual delivery the power. The fallacy of his argument is the "truth" that a strictly OO coded program is a tree with only descending communication. The whole concept is that any two objects can communicate, each deciding whether to respond or not. His arguments are what lead C++ to have friend methods. Encapsulation is broken for convenience.

19[]

You know, I had the typical, knee-jerk reaction that people tend to have when their ideologies are challenged. As an avid OOP developer, I found myself internally screaming out some elegant workarounds to some of the problems you pointed out. Events, for instance, are a great way to talk to seemingly non-related classes without traversing the object tree as you pointed out early on. In fact, many GUI architectures in Java and C# seemingly require the use of this API. However, events can be difficult to implement correctly, and I have seen some horrifying implementations among new developers, so I believe there is some work that's required yet on this end. However, I will say that I'm glad your video was so long. It gave me a chance to get over that initial reaction and take your argument seriously.

You have some good points. Even after watching the video, I still disagree with you, but your video does serve as a nice reminder for some of the bad practices in OOP that I as a developer should stay away from. Even though I disagree and see many patterns whose aim is to solve the problems you're speaking of, this video drives good development practices, both in a procedural and OOP manner.

Rather than the problems you discuss in the video, I think my real complaint with OOP is the learning curve. Because it typically has a steeper learning curve due to the amount of patterns and practices that developers should know about in order to write effective OOP code, I think it's quite common to see some horrifying code in OOP code bases. Either those developers don't take their own development as developers seriously enough to learn why some of these patterns/practices are necessary/useful, or they aren't experienced enough in a wide enough variety of code bases. Either way, thank you for your argument. Whether you're right or wrong, the end result is to create better developers, which I am very appreciative of.

20[]

ust some background: I started playing with computers in the early 1980s, at the age of 12. Object-oriented programming may have existed back then, but I'd never heard of it. I started out with BASIC, then Z80 assembler, then Pascal, then 8088 assembler, then C, then 68000 assembler, then C++, then Perl, then JavaScript, then PHP, then Java, then TypeScript, and I'll forget dabbling with stuff like Modula-2, Expect, awk and TCL that are fringe languages at best. In short, procedural programming sucks. I've done it for some 20 years and it has no redeeming features over object-oriented languages as we know them today. The major difference between procedural (let's say C) and object-oriented (let's say Java) is that, with object-oriented programming, you can choose what data and code you want to group together. You can totally do procedural programming in Java, but doing object-oriented programming in C (such as AmigaOS did) is going to be a hassle. This video could have been good, but instead you ended up with a mess, raving on about long functions (which is a total non-argument), and trying to portray object-oriented programmers as some sort of zealots, waving the feared black flag with the coffee cup.

You mention "ideology" all the time, like object-oriented programming is on the same level as separatist movements, or loonies with beards that run around in the desert. There are many approaches to programming, and different kinds of problems require different kinds of solutions and methodologies. Object-orientation just so happens to work for a remarkably large percentage of the code that is being written. It allows me to not care about what happens in a piece of code that somebody else has written.

They could change their implementation from using TCP to using mail pigeons and I wouldn't be the wiser, except for some greater lag. Object-orientation really means "I don't care about how code works, as long as I know what it does". And the latter you can test with test-driven development. In real-world scenarios, many people work on different parts of the same software. Good luck trying to do that with procedural programming. Because code and data are separate, you need to know both. If you change one, the other one breaks. If the guy next to you changes one, your code breaks. Pure object-oriented programming, as envisaged by the guy that developed Smalltalk, is indeed not very practical. But nobody writes code that way. And as for functional programming, that's the latest fad.

I personally distrust any methodology that refers to input and output (what all programming is about) as "side effects". Sure, you can do wonderful things with functional programming, and immutability is great (and a total pain to try to do in something like Java), but again, it's an approach. It's not the answer to all our prayers for the ultimate programming language. If your logical reasoning is in any way reflective of your programming skills, I'd wager that this video harms your career prospects.

21[]

Well, I've been a programmer for 40+ years. Everything is a trade off. I've seen as much or more hellacious code in OO as in Procedural. "Abstraction" is a big point in OOP but abstraction means obscuring, hiding. Inheritance means instead of seeing and knowing something obviously you have to hunt for it and then figure out what is happening when. It's a trade off. Some minds relate to OO approach better than others. Confusion is there in any approach. Some people like to be cleaver...they tend to like OO. Some people like to be more straight forward, they tend to like procedural.

I think most people don't relate well to OO for a natural reason. But the industry promotes OOP, and as a conspiracy nut, I would say that OOPS is passed down to companies by gatekeepers working for the Jesuits to complicate business and make it harder for the average business to thrive.

For example the idea that you code for long term maintainability seldom manifests in reality. Most older system are rewritten from scratch not evolved. Understanding a complex OO implementation is easily if not more difficult than the same system would be in procedural. Someone who relates to the abstraction of OOP wouldn't agree. But that's a particular nature and not really the merit of OO for the average developer.

22[]

Every project may require unique tools. Or in other words, the chosen language to implement a software application depends on the requirements. Therefore, it can't be assumed that "OOP" is bad in and for every case. With that said, nowadays software requirements do change nearly every day while demand new features. With OOP we have the possibility to write less and reuse a LOT of code while keeping the maintainablility. OOP done wrong may not profit from the benefits; Thus, could lead to the assumption that OOP is bad, even though it heavily depends on the programmer's skills and knowledge base.


23[]

he way you propose a solution to the "problem" (Talking up the hierarchy by changing the return value of a function) would actually be an extremely bad solution. You basically would call a method to let the program check it's own state every few milliseconds and suddenly you have to deal with even more states, states where the another branch has the wrong state because an update wasn't performed. Yes pooling is performed sometimes but it is never my preferred option. Callbacks would be better but that somehow violate your rule where suddenly a child has a reference to the parent, or at least to one part of it.

To the argument that OOPs just give us the illusion that they are simpler, more elegant, flexible, ... . I don't see how elegance or structure can be an illusion if they are mostly only attributes that appear to the person who programs the computer doesn't really care how structured or elegant your program is. If the programmers thinks that the way something is done in Java is more elegant than in C that it is more elegant there is in my opinion no other measurement for elegance. "Inheritance is irrelevant" seems wrong to me. Inheritance is the biggest reason why I use OOPs.

I can have two similar Objects, in a game for example where I have a player and an npc and I don't have to make a function for every single possible interaction between all kinds of data structures. (interaction_player_npc, interaction_player_animal, interaction_npc_animal, ...) I think many people can agree that only looking at overall possible states is not the solution, it was in times where computers didn't have the power to have process an almost infinite amount of states but today they can and the whole point of a programming language is to make it readable and easy to understand for humans and machines, there is no other point in not programming in assembler for example if it weren't that it is just hard for humans to understand it and build complex structures in it.

24[]

LOL that's awesome about the function names! Why the heck are C functions so cryptic? Like strcpy/wcscpy vs. oh, I don't know, SetStringValue? :D But all joking aside, I recently realized exactly what you were saying, and have fallen in love with procedural programming. I find it actually solved a lot of my problems (ESPECIALLY in JavaScript lol) and it just makes the code easier to understand. I know a bunch of guys - intelligent, tech-savvy, brilliant guys - who understand procedural programming but struggle to understand OOP. I do understand it of course, even concepts like multiple inheritance, encapsulation, polymorphism etc. but I've had a hard time explaining it to them in a way that makes sense. I think you'r eon to something here. :)

25[]

I used to write Structured programs in PL/1 and in COBOL, then moved on to NATURAL, and then Visual Basic and Java, and finally Python. I use Objects sometimes, inheritance rarely, parameterised calls often. MY overall perspective is that functions/procedures need not be tiny (a screen or less) and that larger functions/procedures can serve a system very well. The trouble is that many of the junior programmers leap into complex object hierarchies immediately and because one must work with a team and many members of the team will be recent graduates with almost nothing but OO languages at their command systems get stuck in the morass of huge object hierarchies. It is not easy to avoid.


26[]

I will admit it is an interesting critique, however, it mostly consists of strawman arguments. For all that criticism of OOP as being unnatural and not down-to-earth enough, your arguments completely fail to provide any concrete examples where OO modeling fails. You spend almost an hour waiving your hands in the air and coming up with all sorts of theoretical problems that supposedly appear in all those OOP programs and that are completely unsolvable. Not backing it up with examples is intellectually lazy and unscientific. Furthermore, you misrepresent some pretty important ideas that OOP brings to the table compared to procedural programming. To follow my own gospel I will give you a concrete example. You talk about OO design often creating a need for as you call them "pseudo-types" like managers and factories. Then, your argument goes, they supposedly only exist because standalone functions and procedures are not allowed. So, in conclusion, they are useless as a tool - only a product of an OOP dogma. This sort of reasoning is naive, superficial and based on false premises.

Here is why. One of the fundamental differentiators between programming paradigms is what they require to be "first-class citizens". For instance in functional programming functions are necessarily first class citizens - can be assigned, constructed, combined just like any other values during runtime. It is therefore easy to have a function like "fold" that depends on one or even multiple input functions. However, this approach doesn't really scale to entire modules. For instance, it would be difficult to have one part of the program use interchangeably different crypto implementations based on availability within a particular system. OOP brings classes to the table as first-class citizens to address this issue. Now it's easy to have one module depend on another module and have that dependency resolved and managed during runtime It might not be the best solution but it certainly is a solution. What does purely procedural programming bring to the table to address this trivial use-case? Putting a switch statement everywhere? A solution is better than no solution at all.

Factories and managers are not there because we need to put functions in useless dumb wrappers. They are there because that makes the underlying implementations first-class citizens and that is the whole point. Failure to understand that demonstrates a misunderstanding of the very core of OOP. In effect, what you criticize is not OOP but rather your convoluted interpretation of it.

27[]

I watched the whole video and throughout, I was trying to figure out what your path to your questioning of approaches and your conclusions must have been. It seems to me that your OOP experience came from Java where an independent function does not really exist. It has to be (and you say it: you can break the rule) introduced as a static method. Then the fact that you still use the word 'message' for what C++ programmers would call method made me think you must have seen the early days of OOP. What I agree with is that you shouldn't try to stuff everything within an object and that there's a lot of things to do with functions. Take the C++ standard library. It has quite a few objects (containers such as vector, map, list, queue etc...) but it is most importantly also algorithms.

I don't think OOP should be understood as antagonistic to functions (and if I understand you correctly, you seem to think some levels of structures or objects is still a good idea). I think that the trouble is that the kind of OOP you are thinking of is to stuff everything within a hierarchy of objects. I don't think that's what modern OOP should mean. I think a good object is an object that encapsulates a set of data that need to satisfy some invariants. The methods attached to the object should be all the ones necessary to maintain those invariants. fFinally methods should be provided to avoid doing 'translations' in multiple places. That is, avoid having to write complex lines of code to represent a simple concept attached to an object. This latter part is a fundamental lesson I learned from a book by Bertrand Meyer (I think it was "Object-Oriented Software Construction").


That book was trying to push for the Eiffel language which I don't care for, but the idea of avoiding repeated translation was to me the fundamental idea and lesson of the book. If you haven't read it, I highly recommend it, but only really for this notion of 'translation', i.e. having to write a.v[ a.numColumns*j +i ] to access a matrix element instead of a(i, j). When you have to keep translations, you make mistake. (Do I write a.numColumns*i+j ? or a.numColumns*j+i)The code should look like what you think, and good OOP enables that. in C++ an operator()(int i, int j) for a matrix class does that. It allows you to think once locally only about the notion of a matrix and never think about it again. Everywhere you need it, you know it does the right thing. There is one more problem I noticed in your video that I need to bring up. You made this in 2016 and starting at 40:45 you start talking about your desire about anonymous functions and then you describe C++11 lambdas and you repeat many times that it does not exist in any language.

Well it does. C++11 lambdas do exactly what you want and they have existed for several years before your video. The capture [x,y] in C++11 gives you exactly what your "use x, y" represent. Finally please stop praising long functions. They are really not readable. Nobody can wrap their mind around functions that are more than one or two hundred lines, and even then, you can only do while writing it. When you come back, a year or two later, you won't find your kittens in the litter.

28[]

Thanks very much for this excellent lecture. In the very late 1980s, I started with Smalltalk and although certain aspects of inheritance and encapsulation were certainly cool, at least for the first few days, it very quickly turned into a straitjacket. Years later, I realised that a simplistic coding style which favoured procedural programming and judicious use of "object-oriented" features such as polymorphism, overloading, and classes for concrete data type construction (think complex numbers, quaternions, and the like) worked well for me, further not going too deep down the language feture rabbit hole allowed simple code movement among a set of compatible languages such as Java, C#, D, and C++.

Over the years, I came to believe that the few years I had spent with Smalltalk were largely a waste of time, save for maybe forming an informed opinion, and that my time would have been better spent mastering C++. I also saw that Smalltalk's brief period of growth conincided with the introduction of Windows programming, where inheritance as implemented by Smalltalk was actually quite reasonable. If it doesn't help relieve the tedium of one or another aspect of programming, help you get the right answer more quickly, or at least make it a little easier, any language paradigm is worthless. With great responsibility comes great freedom. (From one of the mentioned lectures)

29[]

Disagree. Your argument seems to be “bad code design makes OOP bad” which is the exact same as any other paradigm. OOP is in essence an extension of procedural code. It’s the natural evolution of procedural programming. The problem is that programmers do too many hacky fixes, and that then leads to issues with the code base. Thinking before you code and proper refactoring (agile programming really) leads to fantastic and efficient objects. And that leads to fantastic and efficient encapsulation. There’s not a single thing procedural programming does better than OOP in theory, because OOP is procedural with added power. Also, 90% of your “what to do instead” are things which we are taught to do in OOP. I don’t understand why any of this would be exclusive to procedural but not OOP.


30[]

while I agree that almost all decent designs end up being hierarchy, I’ve never heard of a class not being allowed to reach into its grandchild. I think this is a straw man.... Anyone with a brain would pause — what you just described would create classes with methods that have no relationship to their function and only serve as an interface to the classes below them, which is asinine. Nobody designs or writes programs like that because it would be totally unreadable and nonsensical, and very tightly coupled. No OOP proponent seriously prescribes this design in the way you describe it for the same reason. It totally blows apart any notion of decoupling in one of the most obvious ways possible. Seriously I don’t like OOP (so I figured this would be red meat for me) but what you just described here makes me very skeptical of your experience or where you’re pulling the definition of “proper” from. What you’re arguing against is terrible OOP design on the basis of a misunderstanding of OOP design


31[]

All great softwares we are using today were writing prior to OOP (Unix/Linux to name only that...), so everything can be done without OOP. You just need real programmers to write the code. Since the day I was teached that concept in the 90s, I have always opposed that paradigm that slow down development and empedes freedom. All the goods it brings is nullified by the useless complexity you also need to deal with. Great programmers never needed OOP to produce quality code. Sloppy programmers use OOP to spit code monstruosity that we are stuck with forever now. And when I say that, I think about Java mostly: the single and greatest mistake ever done to computer science. We tried to replace COBOL for 30 years with something better, and now we are stuck with Java that is exacly doing the same thing that COBOL did and we will have to eventually replace that 'dinosaur' sooner than we think.

32[]

Object oriented programming maps to how we use language. subject.verb(object) maps to our language as you said at 13:30. It give more clarity because it puts the subject first. If we did as you suggested and put the argument first it would lead to weird code. Its like saying. The ball was thrown by Frank. instead of.. Frank threw the ball. More clear and concise. However I might be biased because I started with OOP and have not done much with procedural programming.

33[]

I think you generalize too much. Most of the issues you bring up are issues with Java, not OOP. And when you bring up an issue that stems from OOP-design, it's BAD design. You can write inefficient with any kind of programming approach (I've seen 2000-LoC-main-functions and huge messes of interacting objects), bad programming/design is not inherent/exclusive to any one approach. You actually make that point yourself: "absence of structure is more structured than bad structure"... that implies "good + structure = more good" I agree on one thing though: the culture of OOP that evolved around Java is a mess. Factories everywhere, classes named after design-patterns instead for what they are/do. Hardcore-OOP-purists love Java, everyone else hates it(and those purists). There are other languages/SDKs though that have a more reasonable approach to OOP like C#, python, even C++ -- I suggest you try those and expand your horizon instead of criticizing an approach based on one bad example. OOP is no worse or better than functional or procedural, it's what you make of it that is good or bad. OOP has its merits and so does FP, I use both for what they are good at: making my good design easy to handle and making my runtime/state-handling less of a mess.


34[]

There are few messes worse than multi-threaded and distributed systems designed and written using procedural constructs and languages. I will concede that a lot of procedural, rather than object-oriented, code has been written in Java. I once had the pleasure of debugging a 5000-statement multi-threaded Java class that looked like it had been written by a beginner C programmer. I would not wish to repeat the exercise. Of course inheritance can be badly conceived and executed. No programming language can make a bad programmer into a competent one, but I firmly believe that highly modular, containerized, cloud-native components are most easily developed with an object-oriented perspective --- and I know with utter certainty that they are far more economical to support, maintain, and enhance.

35[]

He is 100% right, but the management of shared state and data types is meant to make it easier for groups of developers to work together, like shells of private / protected and public functions and grouping state (data) and methods together makes logical sense if you know the domain of the use of your code. However, OOP is proven to be not so useful when it comes to distributed, and reactive systems that manage state. Lamda functional code is more transplantable and thus is more refusable. Being encapsulated within a defined set of state, and being locked it particular usages of a code, effectively becoming a code hierarchy, of dependency which is "inherently" bad. So how do you solve the depency and inherency hell? Well, you work with single functions that are not reliant of heavy data encapsulation or type basis. Why not make a copy function that can just copy anything, there is one, and it doesn't require a class, it is memcpy.

So what is the problem here? You want security, and code encapsulation. Encapsulation and security (private methods) are only truly as good as the privilege protection on the VM / JVM / CPU / hypervisor platform. Java generally tries to avoid references, because we don't really want to deal with pointers. The operating system does not provide a class for memcpy, but rather exposes the most low level function. Class protection and all the crap that prevents your introspection is fluff on top of the bare function / methods. However, grouping functions and data together (or atleast having the ability) makes perfect sense. You want to have a button, then the button is based upon a clickable rectangle. The patterns to build up to commonality and reusability is in itself OOP. However, you cannot discount the value of providing encapsulation as information value added service, cross cutting concerns aside.

36[]

n my 40 years of programming, I've only seen OOP done right ONCE. The tech lead was a genius who had memorized ~2500 APIs of the existing classes of a large Java project, and could direct newbies to where in the code base to insert their new code, and prevent others from reinventing existing code. ALL other projects I worked on became or were already unmaintainable OOP spaghetti code. Mr Will knows of what he speaks!! Now that I'm retired, and doing my own big data projects, I no longer have to use any OOP code, and I'm glad of it. My errors (and yes, even after 40+ years there are plenty of them!) are easier to find. I should also add that the hallmark of good code is that other programmers can easily understand what you've done and easily maintain it. Those that adhered to strict standards of OOP are like people who get As in creative writing classes. The creative writers rarely go on to write best sellers anymore than the hidebound OOP programmers go on to write understandable code.

37[]

i think the fundamental problem of OO programming is that it takes discipline to do correctly. You can write bad OO code as well as bad Procedural code. The concept of OO design is not inherently bad, but it IS more complex to understand. His reasoning does not tackle the fundamental concepts of OO design, but rather sets up a situation where it gets difficult to track down how a piece of code works because it was poorly written. This can be true regardless of the design paradigm a person chooses. OO was born out of procedural programming because it was difficult to track data state. We needed rules built into the language to control data access and control. Having said that, I almost never see code that is properly written with good data hiding and encapsulation. For most developers it's too difficult a concept to wrap around. Hence you have code that is full of accessor methods, which completely breaks encapsulation leading to the mess I think the presenter is warning against. If you aren't going to do proper OO design, then yeah, maybe just do procedural design and get rid of the complexity. It's like using a high end DSLR camera when all you know how to do is take snapshots. Just use your phone then.


38[]

It sounds less like there is a problem with OOP, but more like there was a problem with you and others that treat ideal OOP paradigms like religious doctrine. The point of programming isn't to make museum pieces that to exhibit how well you follow paradigms to the letter, the point is to make working code. If you have to bend or break a rule here or other, go for it. As soon as you suggested moving some functions into a data type for convenience, tada, you are suggesting OOP. And single concerns is not a hindrance and doesn't mean that every line or two of code has to be broken out into its own method, it just means that each method should be focused on one job. I'm seen plenty of methods with hundreds of lines of code that are squarely in the realm of having a single concern, it is just that the single job they do takes lots of code to accomplish.

Fundamentally, it comes down to pure OOP, or whatever you want to call it, are a bunch of ideals created by ivory tower types that wouldn't know what real world coding was like if it bit them in the rear. Those of us in the trenches would drop OOP in a second if functional or procedural programing provided any real benefits, but they don't. Taking the good parts of OOP and dropping the unrealistic parts is the best way to do things, plain and simple. Lastly, you almost completely lost me at the very beginning where you denied that suits stick their noses in technical aspects of the job. Suits stick their noses in everything. But I agree that it wasn't the suits that brought OOP to prominence, it was the common sense benefits of factorization, single concern structure, and imitating the way our brains are already built to understand objects and their properties.

39[]

Wish people understood the difference between Object Oriented Design and Object Oriented Programming. Object Oriented Design encourages people to consider data in conjunction with the program itself. Object Oriented Programming is an attempt to force Object Oriented Design with linguistic structures. One can achieve the basics of object oriented design with a functional language. OOP became super popular because of Windows and WSIWIG design. Windows used C++; so you had to use C++ and OOPS to write code for Windows.

Interestingly, OOPS doesn't work well for web program. This is easy to prove. Every resource on the web is referenced with a URL http://example.com/file?query=string Every URL is a function with parameters. Functional programming is the best paradigm for web programs. I am surprised people haven't figured this out.

40[]

7 years of programming here - started OOP with "Think Class Libraries" in 1991. Pushed my employer to go to C++ in 1993. Loved Java. Hate Java. Objective-C ( Java's bastard father )...Etc. etc.. His main point, I think, is where he says that when doing the data analysis, you start having to add classes that aren't part of your data. That begins the transformation of all kinds of service classes talked about in the "Gang of Four" "Patterns" book, which is really a book about how to deal with class structures without wanting to commit suicide.

Some things just shouldn't be put into ever more discrete classes - they're simply too complex. I've found that happens a lot and when I create a class that has lots of aggregation in it instead of parceling it out to subclasses, I get yelled at - except by the people that have to maintain my code. My code is usually between 10% and 25% as large as anybody else I have ever worked with. It's tight because I don't go off into OOP outer space. (Comment: software engineering doesn't exist).

Finally a specific case where I believe a library architect got most of it right - that was AngularJS ( 1.x ). The $scope concept and how it worked within a UI is a beautiful thing to behold. It allows one to have most of the focus and compartmentalization that OOP promises, while still allowing extremely complex or large data structures to be displayable and modifiable. I tried several times to get my fellow engineers to understand how it worked, but they just couldn't grasp it. They marveled that my code was virtually bug-free and tiny, and easy to follow, but couldn't understand how I did it.

Unfortunately for Angular - the clowns who decided to junk it and go to Typescript ( forcing OOP and an abominable syntax atop Javascript ) and its stupid "component" architecture which threw away the $scope concept and went to an amazingly and gratuitously complex library that gets you 5 source files instead of 1. Angular2+ is horrific and a great example of library "architects" that get fascinated with their own "elegance" and completely forget about their users.

41[]

Inheritance is certainly useful. You can overuse it, but saying "inheritance isn't defensible" isn't something I can agree with. I also strongly disagree with him that go's error returning is better than exceptions. Exceptions are SO useful. They free you from having to worry about checking errors every single function call. You can catch and deal with errors only at critical points and simply leave the rest of your code clean and assuming success.

But to the main point of OO, he asserts that the moment one object knows about another, its the same thing as a global variable.


This isn't true at all. The whole point of encapsulation is to minimize the amount of data/code you have to know about to properly understand that encapsulated thing. To understand A, you only have to understand the APIs of all the pieces of code A touches, not the whole program. (Comment: which is irrelevant to the point made, you still have a global variable)

it also sounds like he's arguing against the single responsibility principle, which I think its critically important in software design. I agree with him that it sucks when some codebase splits every individual function into a separate file with its own class. So maybe it should be renamed the "minimal responsibility principle". I have no problem having a file with 5 or 6 pages of code, as long as the code contained in there is organized in some kind of inner modular structure. His explanation of the "true encapsulation" graph is interesting, because I use that kind of structure pretty strictly in our frontend design, where each visual component is made up of smaller visual components, and they communicate to their parents through event emissions. I suppose my application is "half-assed encapsulation" like he mentioned, where some parts are stricter than others. I think any encapsulation provides value.

Perhaps a full-assed encapsulation is better than a half-assed encapsulation, but every pieces that is cleanly encapsulated makes it easier to understand and work with that one piece. With enough pieces like that, your codebase becomes way easier to work with, and just those places where you half assed it will be more difficult. I guess i generally agree with a lot of what he says, but the way he starts out saying it are a bit misleading. Like, he's not actually against classes or some use of OO, and he's not really against the minimal responsibility principle. I agree with all his points at the end except for his specific advice about long functions. Its very much a good idea to extract unrelated parts of a function into separate functions. You can write those individual functions in the order they're expected to be run, to decrease cognitive load. But splitting them apart makes it a lot easier to understand what each does, and makes it harder to accidentally/lazily add entanglements between those pieces. Ok I've written far too much. But yeah good lecture, some misleading stuff in there tho.

27[]

objects are state[]

around 18min

allmhuran wrote: Here's just one, simply to prove the point. It's taken directly, verbatim, from the video.

  1. P1) Objects are state
  2. P2) Messages (strictly defined) can only send copies of state, not references
  3. C) Therefore, messages (strictly defined) cannot send object references

The problem with this syllogism is what is meant with object?. https://en.wikipedia.org/wiki/Object_(computer_science) writes "... An object has state (data) and behavior (code). Objects can correspond to things found in the real world. So for example, a graphics program will have objects such as circle, square, menu ...". Your mental or behavioural "state" has nothing to do with domain range mapping of data, volitionalistic language allows for a category mistake when stuffing the functions inside a Struct.

MrSwanley[]

".....9 months ago (edited) An interesting video, but like some of the other theses mentioned, this one rather overstates its case. To pick one example: it claims that modifying a state by passing a message is just as bad as modifying a global variable. As someone who has written and had to maintain code over multiple decades, I can tell you that this is plain wrong. When you have a global variable you have intimate knowledge of and access to the implementation of a state. With messaging you do not. With messaging it is possible for the responsible object to be replaced by another module with a completely different implementation, without the client modules being affected. Code which relies on global variables will break. Code which does not will keep going. This is a huge difference, and not something to be glossed over.

Btw, I speak as somewho who developed through the Pascal and Modula-2 branchs of programming, eventually ending up doing modular programming in C (not C++). Yes, the full Petzold and Win32 API. I appreciate and occasionally use object oriented DESIGN (imho this talk rather conflates OOD and OOP), but I have no use for OOPLs (including C++) per se... I just find that they don't do anything to makes my life easier, which is what good design principles should be all about. ..."

links[]

oop

Ycombinator good buy object oriented programming


Alan Kay

Advertisement