Is OOP EVIL??? Reacting to my favorite dev Youtube video

  Рет қаралды 126,043

Theo - t3․gg

Theo - t3․gg

Жыл бұрын

Seriously Brian killed it w/ this video and it aged hilariously well
• Object-Oriented Progra...
Huge s/o Idez as always!!!
Follow me on...
Twitch: / theo
Twitter: / t3dotgg
Instagram: / fakiebigfoot
Everywhere else: t3.gg/links

Пікірлер: 559
@turdsalami
@turdsalami Жыл бұрын
There's something I've learned in the last 10 years of programming. This industry REALLY loves to claim that the thing they're doing is the best way to do that thing.. this language is the best, that editor is the best, this paradigm is best, etc.. bunch of pretentious people.
@unifiedcodetheory8406
@unifiedcodetheory8406 Жыл бұрын
It's not really out of pretentiousness, it's more out of greed. If someone claims that what they're doing is proprietary or special, they will make more money doing so.
@vincaslt
@vincaslt Жыл бұрын
Probably simply confirmation bias.
@h0ph1p13
@h0ph1p13 10 ай бұрын
@@vincaslt For the "simple" people yes. But for the ones who know what they're doing it's $ales $ales and more $ales.. yes.. on open source too.
@adambright5416
@adambright5416 9 ай бұрын
php is the best
@b_delta9725
@b_delta9725 6 ай бұрын
being honest, this isn't just the industry, programmers love saying that all the time. even if they are right and something is somehow "the best" for a certain scenario, they are constantly pretentious about it. so i don't think it's greed as other person says, just their own life experiences as programmers with their ego multiplied by 4
@Bozeman42
@Bozeman42 Жыл бұрын
"you end up having to jump all around the code to find any logic" I ran into this at work. Took forever to find code that actually did anything.
@ravenecho2410
@ravenecho2410 Жыл бұрын
that's call depth. not functions. as long as call depth is minimal, and functions are well name. making functions helps. call depth shouldn't ever exceed like log (count functions)
@noahfletcher3019
@noahfletcher3019 Жыл бұрын
@@ravenecho2410 Yes but OOP encourages breaking everything up which leads to these call depths. Furthermore, having a call depth issue with just functions is way easier to follow than a call depth with classes that call their functions which instantiate other classes that do the same and so on and so forth. I am currently dealing with this at work. I get on with it but it is a waste of time.w
@FADHsquared
@FADHsquared Жыл бұрын
"single responsibility" they said
@salluzziluca
@salluzziluca Жыл бұрын
This can be solved with a UML diagram... but all my homies hate UML diagram
@noahfletcher3019
@noahfletcher3019 Жыл бұрын
@@salluzziluca haha I don't think I've even seen a UML diagram since university and I've been working professionally for years.
@DavidWoodMusic
@DavidWoodMusic Жыл бұрын
Theo I kid you not, I've watched that video every 6 months since I started programming. I went from not understanding it, to kind of understanding it, to violently agreeing with it while drinking myself to death I miss my wife
@daleryanaldover6545
@daleryanaldover6545 Жыл бұрын
I watched this 2 years ago, now this is my 3rd year as a developer and I strongly agree with Brian. Although my work tends to involve OOP most of the time, I try to minimize it and make it simple procedural.
@sortof3337
@sortof3337 Жыл бұрын
i love that i miss my wife in the end.
@kibe2134
@kibe2134 Жыл бұрын
I miss your wife too.
@DavidWoodMusic
@DavidWoodMusic Жыл бұрын
@@sortof3337 She was just at Target when I was writing this. She is home now but she wants a divorce.
@vioricasuper4127
@vioricasuper4127 Жыл бұрын
@@DavidWoodMusic Sorry bro
@ahmadkhatib3117
@ahmadkhatib3117 Жыл бұрын
I just watched Brian Will's video last week, I regularly watch it. Thanks for bringing attention to it, considering how old it is. The more I've grown in my career the more I resonate with his views (and John Blow as well). I really like that your videos cut through the dogma in programming and just focus on getting meaningful work done.
@travism70
@travism70 Жыл бұрын
Functional core, imperative shell was the thing to finally make pure functions/functional programming click for me. Wish it was brought up more.
@spacey_sooty
@spacey_sooty 8 ай бұрын
30:27 I write OOP robotics code in C++ which writes code this way with near 100% consistency. It has actually been a huge step up from writing more C style code and allows us to effectively manage state.
@9SMTM6
@9SMTM6 Жыл бұрын
Rust actually allows 2 of the points in a genius way that I've yet to see elsewhere. For starters the code blocks with "{}" can actually return a value (they return the last expression if you dont add a ";"), so if you have to do a few steps to create some datatype you can just assign a block to it where the variables are contained. Then in terms of modularity. Rust still has encapsulation, but it's on a module level: If you create a struct (rust doesn't have "classes", but structs can have methods), and don't make some fields public you can still use these fields in the module, not just the struct methods. {} blocks are also especially helpful when combined with RAII (which I find to be a brilliant concept, and sorely miss in other languages, though to be fair C++'s implementation is problematic, you want affine types and move-by-default for this to reach its peak). To restrict access to the outside state you would also need use immediately invoked functions. But with Rusts (deep!) Immutable-by-default and borrowing rules I have not found it necessary.
@thebutlah
@thebutlah Жыл бұрын
I also think that rust's ownership model forces you to take the "single tree of references" approach, because of its single ownership model. Circular references aren't (easily) possible due to the lack of garbage collection and borrow checker. You will almost never `new SubComponent(this)` in rust, but its *extremely* common in Java. Also, rust makes it natural to split a library or application into multiple crates, which fits nicely into Theo's argument of "programs" or "libraries" as a way of organizing code.
@9SMTM6
@9SMTM6 Жыл бұрын
@@thebutlah Yes indeed. Although, to be fair, it does make some things a bit difficult, particular in UI. I really want to get around to trying Yew one of these days, a React Clone in Rust that runs in WASM, I guess then I'll see how well borrowing works with Reacts one-way data flow.
@thebutlah
@thebutlah Жыл бұрын
@@9SMTM6 I would expect that one way data flow fits very well with rust, but I've never used react
@redpepper74
@redpepper74 Жыл бұрын
As someone who’s only really seen glimpses of Rust: what’s the difference between a class and a struct that can have methods?
@9SMTM6
@9SMTM6 Жыл бұрын
@@redpepper74 I will only guess as to the motivations. There is probably a good reason that you can find somewhere, these decisions are often made public, but I'm lazy. My guess is that (not necessarily in that order nor exhaustive) 1) it's easier to explain than classes. 2) it better describes the semantics Rust aims for, being more data centric. You've got some data, and then you define operations on that data. You can have multiple blocks where you implement "methods" (associated functions that take self), in fact you have to implement "interfaces" (traits) seperately, and you can implement traits for types from the standard library (with some limitations im not going to go into). 3) you can in fact not only define associated functions and implement traits for structs, but also enums 4) neither rust structs nor enums do have Inheritance
@Mentioum
@Mentioum Жыл бұрын
Brian Will - legend. I only knew him when I needed to learn Clojure forever ago since apparently Cambridge Uni (at least back then) was obsessed with getting CS students to write things in it. Pretty mental he works with Unity given you basically HAVE to do OO when working with the engine, or at least it pushes you extremely hard in that direction. Perhaps a less than popular take given this video, I actually really loved working with OOP in Unity as I felt like as long as I didn't make any stupid objects of my own the objects given to me by the engine were really nice.
@raylopez99
@raylopez99 Жыл бұрын
I think that is the main argument of the advantage of OOP., that you don't need to see the "big picture" if you need to change something, just follow the existing class and make a change by induction, see the Brian Will video "Object-Oriented Programming is Embarrassing: 4 Short Examples" and go to 27:30 mark and the claim by Sandi Metz which Brian dismisses but is exactly that. It does seem to make sense to me, as a hobby coder, to simply "think by induction" and extend the OO class that way, without "really knowing" what the class is doing. Then unit test until you're satisfied the class behaves as you want. As for OO vs procedural (and functional) programming, it's due to the way apps have evolved over the last 20 years to become more "cloud" or "database" intensive (the same reason Python has become popular, as it works well with dB queries I am told, I hobby code in C#, learning Rust, have done SQL, Linq-to-SQL, ASP net). When you are dealing with databases you should not mix classes with data the way OO often does, but instead, "let data be data" as Brian Will says and functionally and procedurally query it. In other types of programs, like game development, OOP is perhaps better (after all a game is nothing but objects interacting with one another), one reason perhaps Unity does C#. And the above is the last word on this topic, commit it to memory, case closed! (smile)
@marcossidoruk8033
@marcossidoruk8033 24 күн бұрын
I think you are missing the point. A bunch of types that act as an interface between library and user code is not OOP.
@patchr6288
@patchr6288 Жыл бұрын
I had a job that touted OOP as the worst thing to ever become popular. The boss was completely dogmatic and convinced functional programming should always be used. Spent hours researching every week and trying to apply new things he had learned to the frontend codebase. I have never in my life, worked with frontend code that was so fundamentally difficult to understand. There never seemed to be rhyme or reason to the code base, the naming of things never described the purpose of the thing (function or otherwise). Making a simple change to the name of something on the frontend required 1) at least 4 different files to change in potentially multiple places in each file, 2) the backend to change, 3) tests to change, 4) plain text/locale files to change on the frontend and backend. The intellisense would not tell let you know when something wasn't quite right in each file, so it would fail at runtime BUT the error message was very cryptic and the stacktrace rarely had the point in code that was causing the problem. So unless you had a very deep understanding of the code it was nigh impossible to debug things (there were many times where I had reached the end of my entire idea list of things to try to fix a problem and had made exactly 0 progress, and in the interest of learning a code base I try and be thorough). This is not a complete list of issues (not even close). Changes for me, as a new engineer to the code base would take multiple hours, sometimes days more than I'd expect if I didn't have one of the 2 engineers who had created the app next to me. In that code base, for some reason strings had been strongly typed akin to an enumeration, and those enumerations would have hundreds of options. One of my first tickets faced a bug where an if statement stopped working because we reached an internal limit to the amount of allowed string enumerations that could be compared (language defined, and I may be forgetting details of the bug but essentially whole app stopped working when adding another thing to a list). And due to the small size of the company and the fact they had not hired anyone since they had started they had no idea of the mess they had made -> they understood it, so it was good, right? No linting, no styling, 4000-20000 line files with no character width limit (longest line was 1000 characters long) filled with small functions with good or bad names and around 50000 tests. Each planning session I would describe the struggle I am having with it, how I believe we could improve potentially improve understanding with better naming or making small files and I would be hit with the same comment each time from the boss, "it just takes time to understand". The backend was a domain driven design inspired architecture using OOP with some functional concepts interwoven (written in C#). There were no issues on the same scale as described above. Every codebase has issues and it can't be avoided, but it was easy to work in and understand and the developer who had done most of the work could point to resources for me to read that he had used to come up with the architecture. I would hazard a guess that anyone, functionally or object minded would have found the backend code much more enjoyable to work in. In both cases I had new things to learn. Functional programming, domain driven design and C# were all new to me. At the end of the 3 months I was there I felt like I had a very strong understanding of the backend and how to contribute to it, and took many things away from the experience of having contributed to it. The frontend I felt like I had made 0 progress at all. This is all to say that no matter which architecture, language or programming paradigm you use, when you use it incorrectly you can still create a hatecrime to humanity. I don't have a grudge against functional programming, I learnt a lot about it and its benefits and negatives because I read books during my short stay there. I still want to apply its concepts to my own projects to at least give it the try it deserves and I certainly learned to more carefully consider side effects and the way I write functions has certainly changed. I have definitely learned that dogmatically applying a concept with no regard for anything else is an awful idea and that we, as developers, should make use of the tools we have available to us.
@____uncompetative
@____uncompetative Жыл бұрын
Thank you for sharing this. I have screen grabbed your comment.
@sacredgeometry
@sacredgeometry Жыл бұрын
The worst codebases I have worked on have been FP, the second worst Data Flow. Its not even close. Almost every FP codebase I have worked on was trash and no I didn't have any much if any part in writing it. It was hardcore FP advocates. The irony is you could see they struggled with it and just wouldnt permit themselves from admitting how fucking awful it was. The take away. People that are prone to religiosity and dogmatism make really shitty engineers.
@bjornbeishline6619
@bjornbeishline6619 Жыл бұрын
I’ve always had an issue with object oriented programming, as programming becomes more of a philosophical exercise, particularly with Java. It’s horrible being forced to write things as objects when in reality they never should have been, or would have been better written without.
@ac130kz
@ac130kz Жыл бұрын
It's even funnier when they say that object oriented means easier to understand
@vd3598
@vd3598 Жыл бұрын
IMO, it depends. I seen really really bad evil OOP and hated it. It was a nightmare to work with. But I also seen really good examples, pleasure to work with. Many people just got it so wrong.
@emreaka3965
@emreaka3965 Жыл бұрын
@@ac130kz Easier to understand. Better.
@NateLevin
@NateLevin Жыл бұрын
The worst instance is java Runnables. It is literally just an escape hatch they added to the language because they didn't want to add first class functions. Just a terrible design.
@igoralmeida9136
@igoralmeida9136 Жыл бұрын
class OrganizationService extends CRUDService
@brandonj5557
@brandonj5557 Жыл бұрын
I completely agree with this discussion; coming from Swift & iOS everything was literally as class. You always had to extend UIView or UINavigationController or whatever & I've been finding in my Typescript & Rust programs that I still kind of have that mentality. I've also ran into the issue where code is so abstracted that I need to look into 5 or 6 objects to understand what exactly the piece of code I'm looking at is doing. With that said I'm definitely going to rewrite my networking code into a more functional manner
@dl0.0lb
@dl0.0lb Жыл бұрын
Saw the thumbnail pop up and immediately was excited for your viewers, this video is such a banger.
@bartech101
@bartech101 Жыл бұрын
Can't agree with one thing, not splitting functions into smaller functions. 1. Who does section comments, I bet most sections won't have description. When splitting you convey what it does by function name. 2. Debugging large function is a nightmare when you have dozens of variables in scope. 3. If else hell and forech loops. To figure out what function does you need to understand whole logic. 4. It's easier to understand the example where you have bunch of small functions called one after the other it's very human readable if good names are used. 5, Smaller functions are easier to test, easier to maintain. 6. Having long function increase probability it will have several side effects. Will read some global state and change it.
@alexischicoine2072
@alexischicoine2072 Жыл бұрын
I tend to just define my functions in order above the final function that calls them that way it's quite easy to read the code and it's nearby in the file. Another thing that's nice is if you're working in notebooks you can put markdown through your code making it really easy to organize your file.
@bartech101
@bartech101 Жыл бұрын
@@alexischicoine2072 I usually define in different order first main and then inner functions. This way when you scan code you got high level view. You got chance to see how inner functions are used. You can skip inner functions details if you don't need it.
@alexischicoine2072
@alexischicoine2072 Жыл бұрын
@@bartech101 that's interesting. That makes me think I should look up if one can call an inner function from outside a function in python. Edit: I looked it up you can kind of hack to do it but it's not ideal. Not sure what would be the best way to test your inner function independently. Maybe you can just test the main function and take out the inner function when developing/ debugging and put it back inside after.
@bartech101
@bartech101 Жыл бұрын
@@alexischicoine2072 I didn't ment to literally put function definition in function. Calling it inner was confusing. I meant extracting parts of main function to few smaller functions and call them in main function. Main function declared first and then below smaller functions.
@alexischicoine2072
@alexischicoine2072 Жыл бұрын
@@bartech101 ah ok yes! Have you found a good way to communicate they're not really intended to be used on their own?
@astartup
@astartup Жыл бұрын
I think the best example fo when OOP is badass is my Script2 Embedded-C++ RPC API and Chinese Room Abstract Stact (Crabs) Machine. It's all contiguous data structures except for the Crabs uses one virtual function (the Star function) to handle the RPC functions and I use some inheritance to automate the manual memory allocation (i.e. the Array class). C++ virtual functions are not portable memory mappings, but the way I did it it works on Embedded as well as desktops. Excessive abstractions are bad practice, but some abstractions are very useful.
@kippers12isOG
@kippers12isOG Жыл бұрын
The feature he was talking about with blocks that “use” copies of variables in the parent scope is basically c++ lambdas which capture by value, so there is one language that does it. I think rust closures might also do the same.
@fededevi1985
@fededevi1985 Жыл бұрын
Love that he is a Unity dev. He basically shits on OOP ( which is fine as far as I am concerned ) but then he uses Unity that is successful and easy to use because someone else put in the effort to make a good and easy to use object oriented library that uses all sort of OOP patterns.
@julkiewicz
@julkiewicz Жыл бұрын
The OOP in Unity is trash. You end up constantly working around the fact that it is OOP if you're writing anything more complex than a simple mobile game. It's so inadequate to what the engine is trying to do. And now Unity discovered that basically their OOP API is holding them back and are trying to redo their entire engine in a more data-oriented manner. And it's not making the engine any easy either. They could have created just as easy API without OOP.
@FADHsquared
@FADHsquared Жыл бұрын
Wait. But isn't the point of ECS to have Components that ONLY have fields (so normal structs literally) and systems that ONLY have methods (so just functions)?
@asdqwe4427
@asdqwe4427 Жыл бұрын
I remember listening to his takes on OOP years ago when learning functional programming concepts.
@codenameirvin1590
@codenameirvin1590 Жыл бұрын
This is a really strong argument for Immediate Mode GUIs. The problem is that there aren't yet any (that I am aware of) that are production ready.
@tomasruzicka7161
@tomasruzicka7161 Жыл бұрын
c++ lamdas allow you to specifically list things to use from the enclosing scope, otherwise you get nothing. Actually if you do not use it it is automatically convertible to a function pointer (meaning no state)
@justed91
@justed91 Жыл бұрын
About the randomly boarding a plane thing, that's absolutely true. In my country, the domestic flights don't really board people from back to front, but when I traveled to America, I remember the line taking at least 2x the time, and it was "in order" Both planes were about the same size and both were full.
@BalintCsala
@BalintCsala Жыл бұрын
48:00 Personally I feel like doing this as a single module (e.g. a single ts file) is a bit clearer, you can still keep the code as a single chunk while minimizing indentation and enabling IDE features, like region folding. It also saves you from documentation rot.
@RobEdwards369
@RobEdwards369 10 ай бұрын
Love this video especially the quote "absence of structure is more structured than bad structure". I'm not really a coder I mostly do CAD. It can be incredibly frustrating when one innocuous design change can break your entire carefully crafted model
@dronevilOO
@dronevilOO 5 ай бұрын
There's no program that has "absence of structure". Files with a bunch of functions also define a structure. When some requirements change you have to move them around as well. This guy sets up a false debate.
@robnauticus
@robnauticus Жыл бұрын
This was one of the most influential talks I heard many years ago. The title was definitely click bait but... Absolutely on point. Glad I found your channel too! 😁
@marna_li
@marna_li Жыл бұрын
Brian's videos are great! They are not to discredit OOP as an approach, but how it is being practiced religiously without questioning its pitfalls. In today's programming language landscape there are so many paradigms and approaches - often used together. Sadly, OOP often revolves around classes, not objects and interactions. It often entails boring Service-classes, which essentially is modular and procedural programming. That is not how OOP was intended either.
@dodgecoates8760
@dodgecoates8760 Жыл бұрын
He’s very explicit that he intends to discredit it as an approach, point blank
@JamesTsividis
@JamesTsividis Жыл бұрын
As a new programmer, I'm grateful to find your channel as you think about the fundamentals of programming and why we do what we do.
@empresagabriel
@empresagabriel Жыл бұрын
"Sure more than half of you have even seen this talk but you are sticking around because it's really good and you like me" That's 100% accurate in my case, ngl
@alexischicoine2072
@alexischicoine2072 Жыл бұрын
I've mostly written python code and I've found importing modules as a name works great for autocomplete you don't need an object just to define some restricted namespace. Simple objects with functional methods like dataframes also work great.
@redpepper74
@redpepper74 Жыл бұрын
Yeah I’ve been working with Python recently and in my experience, small objects with obviously related methods can work pretty well. For example, in one project I have Course and Student classes that each have to-json and from-json methods, and it makes it more manageable to pass around student and course data. However, when there’s god objects and do-ers and other high-level objects, I tend to get analysis paralysis.
@jameender
@jameender Жыл бұрын
It's really refreshing to see people talk about actual problems of OOP
@rogerdinhelm4671
@rogerdinhelm4671 Жыл бұрын
It's not, the whole talk is about very specific case, namely sharing references to objects. And, funny enough, unless you are using a language that doesn't have encapsulation mechanisms, like JS, sharing a reference will not mean sharing an entire object state, which is the case with languages that do have encapsulation and all you get from your reference is a public interface. And shared public interface is not a shared state.
@dHue_52
@dHue_52 Жыл бұрын
I've never done full stack or Typescript before and your videos have helped me a lot with how to make decisions about what stack to use based on the requirements of the app being built.
@awwastor
@awwastor Жыл бұрын
Easily constraining the scopes of variables is one of the best things about many lisps. Many languages allow you to make a lexical scope ({}) which separates out variables, even C/C++ I think. Many newer languages allow you to drop/defer/delete a variable from the scope, like Rust
@BosonCollider
@BosonCollider Жыл бұрын
The C++ lambda is really neat for this, since any capture has to be explicitly declared
@CottidaeSEA
@CottidaeSEA Жыл бұрын
Regarding the myFunc example later on where it calls a lot of functions, I agree to a certain extent. The exception being when your code does alteration of some kind and persists the information. In that case I believe it is better to have the alteration in a separate function. This is so you can properly test the code without permanent side effects. I generally agree with what was said here, although I think there have been loads of improvements in the OOP world to lessen these issues. Needing to add a namespace to stuff through a class is kind of a pain though. As for the tree structure mentioned; that will be present in all systems in one way or another. These issues will always exist in one way or another. Finding the function you want is just as difficult without them being in classes, because it all depends on what you name them.
@lunedefroid8817
@lunedefroid8817 Жыл бұрын
46:43 In the case like this I just make an object with private methods. If it's private, it divides code into chunks, and it doesn't create that extra complexity you can just watch each function separately
@debasishraychawdhuri
@debasishraychawdhuri 11 ай бұрын
I was a full on Java programmer, but I moved to Rust. I just noticed that Java has added a bunch of antipatterns recently into the language. One of them being what they call pattern-matching, which is not really pattern matching. It just lets you convert a bunch of instances of ifs into a switch statement.
@istasi5201
@istasi5201 Жыл бұрын
OOP is not bad, whats bad is OOP being used as a hammer and everything is a nail.
@numeritos1799
@numeritos1799 Жыл бұрын
Indeed, if all they do is web development, it's understandable that they find it tedious. But it should be obvious to anyone who works in different areas/industries that OOP has its place.
@brandonj5557
@brandonj5557 Жыл бұрын
I've found that Networking and Socket programming in hard without a Class, especially if you have a variable that needs to constantly receive bytes from a server until the request is complete.
@numeritos1799
@numeritos1799 Жыл бұрын
​@@brandonj5557 I've only done socket programming in Python and Node, and in both of these, sockets are implemented as classes (although in node they don't use the class keyword because it's old js :)). And I usually end up creating a class aswell to maintain data related to the connection, for instance if I were to implement TLS, I'd have to maintain a bunch of parameters that seem suitable to have inside a class.
@Acid31337
@Acid31337 Жыл бұрын
If instrument encourages people to use it in hammer-nail manner, it is enough to consider it bad.
@numeritos1799
@numeritos1799 Жыл бұрын
@@Acid31337 OOP is a programming paradigm, how does it encourage anything?
@GAoctavio
@GAoctavio 9 ай бұрын
Brian has a few more videos on OOP. I really like the examples one cause it shows how convoluted some "OOP solutions" can be
@rogerdinhelm4671
@rogerdinhelm4671 Жыл бұрын
>Polymorphism in not exclusive to OOP. Procedural code even more polymorphic than OOP Then I am not sure to whose "morph" he is referencing to? Overloading functions? Overwriting function references? What is the mechanism to implicitly switch between forms here? >Incapsulation does not work because I said so I mean, I guess, you are the boss >People liked OOP because of appeal and ease Just becasue something is easy and appealing does not mean it is bad, and just because something is complicated and sophisticated does not mean it is good. It is basically arguments of a hipster - aka "against mainstream". >Stored references is basically a global variable False, since it is incapsulated by those two objects it is obviously not global, it is wider than scope of 1 object, sure, but it is not global. >Object storing references breaks incapsulation because it is a shared state While technically true, I have yet to see any problems arising from it in real applications. On the other hand incapsulation on a class level helped a lot to hide local details. >Where in the system of ten objects, all sharing the state, is a coordination? Assuming he is talking about sharing state only through object references then the coordination is on every object's own interface. Every object declares the rules of how it can be interacted with, through its interface, doesn't matter if it is 1 object it is interacting with, or 100 or 1000. >If we take encapsulation seriously we need to form a strict hierarchy of objects But it doesn't solve the problem you have posed - there are still object references being shared. TLDR The whole talk is no-doubt comprehensive, but the author tries his best to pull or cherry-pick his arguments, questions and answers to fit his agenda and not the actual reality. It seems like all of these arguments are relevant to a very particular field, task and language (seems web-development) but they are far from logical or universal.
@empresagabriel
@empresagabriel Жыл бұрын
>>Polymorphism in not exclusive to OOP. Procedural code even more polymorphic than OOP > Then I am not sure to whose "morph" he is referencing to? Overloading functions? Overwriting function references? What is the mechanism to implicitly switch between forms here? It's to change the behavior of a function based on the type of the arguments -- the function implicitly switches between implementations based on types. For example, function overloading in C++ and Java, defmethod in Common Lisp and Clojure, and typeclasses in Haskell. The alternative way to do polymorphism that is more OOP-centric is more akin to Python's inheritance: the language only allows you to change the behavior of the function based on the class of the instance, but if you need to change based on the type of any of the arguments you have to do it "manually". In C++, Java, Common Lisp, Clojure, and Haskell the language picks the right function specialization for you based on the types you supplied. Note that some languages in that list are OOP-centric, some are OOP-optional, and some are heavily-against-OOP. In that sense, OOP inheritance is polymorphism on a single (or few if multiple inheritance is allowed) types, while more functional and procedural approaches allow you to be polymorphic in any number of types (including non-specified number of types, through variadic templates/typeclasses/multimethods). Hence, functional/procedural code can be more polymorphic, as an object can't have 0 or 20 classes simultaneously in OOP (but a function can easily have 0 args or 20 args or an unspecified number of args). Note that Java does not allow any code outside of OOP (it's not an OOP-optional language), so you can't have "free-floating" polymorphic functions like polymorphic global functions or polymorphic global closures. But in other languages that is completely legal. >>Object storing references breaks incapsulation because it is a shared state > While technically true, I have yet to see any problems arising from it in real applications. On the other hand incapsulation on a class level helped a lot to hide local details. That's the problem with multithreading. When you have multiple threads reading and writing to the same variables -- the same state, now you've got yourself into a problem. And it's and industry-wide problem, as multicore and multithreaded processors are everywhere nowadays, but unfortunately concurrency is still considered an "advanced problem" because most languages default to shared mutable state and shared mutable state and concurrency leads to all kinds of data race bugs that are indeed tough-ish to solve (but are way more trivial with shared non-mutable state or non-shared mutable state). >>Where in the system of ten objects, all sharing the state, is a coordination? > Assuming he is talking about sharing state only through object references then the coordination is on every object's own interface. Every object declares the rules of how it can be interacted with, through its interface, doesn't matter if it is 1 object it is interacting with, or 100 or 1000. But those interfaces only solve the problem of non-shared state (sometimes called private state), not of shared/public state (unless you want to have a maintenance nightmare with duplicated code). Suppose you have a variable that represents an integer that must obey some constraints -- let's say it can only be multiples of 2, so 1, 3, 5, and other odd numbers aren't allowed. If such a variable (which is itself an Object, an instance of some sort of IntegerClass) is shared between 10 objects, each one of a different class, then we need to repeat the constraint code at most 10 times (once for each class) -- otherwise one of those 10 classes that have direct access to the shared state may overwrite it with an odd number which puts it into an invalid state (it would violate the multiple-of-2 constraint). So the amount of objects interacting with a shared state is important, as each interaction point is a point-of-failure where the constraints of that shared state may be violated -- so that's all the places where our constraint-checking code has to be present, and in that example it would be potentially 10 different places. However, once the shared state is no longer shared, that is, when you bundle all the potentially 10 different classes under a single interface/class, then you only have a single point-of-failure. And when the day comes that neither multiples of 2 nor multiples of 5 are allowed anymore, then you only have a single interface/class that you have to modify the code of (compared to 10 classes/interfaces before). And you could have all kind of other divisions, like having two interfaces where one cover 3 of the 10 classes and the other cover the remaining ones, or having 4 interfaces in a 3-3-3-1 split. The best way to encapsulate 10 classes inside of N classes/interfaces depends on context, but having more places to touch when fixing a bug, be it in N=10 places, N=1000 places, or N=2 places, will be worse than changing on a single place (N=1). That is why encapsulation which hides private state behind an interface was a selling point of OOP, but you can only encapsulate state that you own otherwise you won't be able to enforce that the shared/public state will remain valid without removing direct access to that state (where it won't meet the definition of shared state anymore) or duplicating the code that ensures that only valid states are allowed (which quickly becomes a maintenance issue, as every write to that variable would at least needed to be guarded by an if-statement and a call to a function that says if a given number is a valid state for that variable).
@julkiewicz
@julkiewicz Жыл бұрын
You're strawmanning like crazy. Just because he said "People liked OOP because of appeal and ease" doesn't mean he says that we should instead go for sophisticated and complex. Arguably procedural / functional is in fact easier, it's just undersold because of fashion and entrenchment in certain programming languages and their standard libraries.
@VitalijMik
@VitalijMik Жыл бұрын
50:27 yep that is what PHP has, if you define a closure, none of the varaibles above are automatically inside the closure you have to call a use statement or pass them via parameter explicitily $a = 1; $closure = function(){ echo $a; //does not work } $closure(); $closure2 = function() use($a){ echo $a; //yep it works } $closure2(); so PHP is actually awesome ;)
@yyydollars8456
@yyydollars8456 2 ай бұрын
Php is somehow underrated even though it's the most used language out there in web
@merkelizer9940
@merkelizer9940 Жыл бұрын
Brian's point on long functions is great. A CS prof at Stanford, John Ousterhout, wrote a book that came to a similar conclusion that deep functionality > unnecessary abstractions. A Philosophy of Software Design. Fun, pragmatic read.
@fiveljones2340
@fiveljones2340 Жыл бұрын
"There's no reason to use inheritance, it's 2022" Godot: hold my beer
@leosin5767
@leosin5767 Жыл бұрын
Laughed so hard when the win32 thing with Hungarian notation came out
@mfpears
@mfpears Жыл бұрын
38:00 There actually are 2 definitions of "abstract". I talk about this in a video I made a couple months ago about abstraction. 47:00 Another thing I talk about in that video. If you can write a good name for it, abstract it. It doubles as a comment and a reusable piece of code. There's no problem with that. The name says what it does, no need to see the details.
@zacharychristy8928
@zacharychristy8928 Жыл бұрын
Not to mention making it more testable, explicitly separates scope, and doesn't rely on "section comments" which are pointless.
@YTCrazytieguy
@YTCrazytieguy Жыл бұрын
an abstraction that is bigger than a function and a data type can also be a module
@jon_escamilla_
@jon_escamilla_ Жыл бұрын
After seeing your wall of nice headphones; what keeps you or has you using the SHP9500s?
@zacharychristy8928
@zacharychristy8928 Жыл бұрын
It's really funny how often I'll talk to someone who has a strong opinion on paradigms, whether it's "OOP is evil" or "Functional is king" it's always REALLY easy to come up with a scenario that refutes it. It usually results in people conceding "Okay I guess in THAT case it makes sense" when 'that case' is usually just something they haven't done that much. Coding is effectively a method of communicating how to solve a problem. If the only problems you solve are in web development, it's going to seem like the whole world is crazy for using methods that don't fit into that problem. I work on large desktop applications with lots of inherent state and complex functionality, calling through various layers that all serve a specific purpose. Can you imagine coding something like SolidWorks using the methods he's describing? It would be a completely unserviceable mess. It's why I've grown to love languages like C#. You have all the tools you need to solve the problem the best way you can. LINQ for problems that are handled best in a functional way, Objects for cohesive/reusable 'modules' of functionality, with juuuuust enough access to low level concepts that you can do some useful tricks.
@Elite7555
@Elite7555 Жыл бұрын
The problem with OOP is the notion of polymorphism through inheritance. We have to conform to all this OOP bullshit, just so the compiler can hide the VTable from us.
@carlyounger6262
@carlyounger6262 Жыл бұрын
I literally turned a bunch of functional code into a couple of classes yesterday. The code wraps a shader with an API, and it all worked really nicely without OOP, until I needed to support creating multiple instances of the renderer. There was no sane, functional way for the API to associate each shader with its own collection of twenty or so variables (which where originally just module-wide globals). The OO approach did everything OOP is meant to do for you. Right tool for the job.
@xeoneraldo1254
@xeoneraldo1254 Жыл бұрын
I completely agree. There are scenarios to use functional / procedural programming, but time has proven those don't scale well. OOP is the way to go especially for huge systems and complex applications. Can you imagine software like Premier Pro or Photoshop being written with those things the video said? The video creator really must be stupid to do that. They obviously know the right thing to do, yet they continue to do otherwise just for the sake of "being different" just like other cults.
@alexandredaubricourt5741
@alexandredaubricourt5741 Жыл бұрын
Screw those hypesters. Abstraction is the point of programming. Now if some people have trouble with inherited code messing up and like to blame it on the tool rather than themselves so be it..
@grawss
@grawss Жыл бұрын
@@carlyounger6262 Whatever functions created the renderer and the collection of variables, just run those again. That said, it sounds like you had trouble with the data structure, so you restructured the data to use classes. Just restructure the data to use functions and you're golden. Associating something, or multiple somethings, with some variables is nbd for functions.
@aidanbrumsickle
@aidanbrumsickle Жыл бұрын
You can do something very similar to his idea of a use block in C++ with an immediately invoked lambda that captures the required variables by reference and doesn't take any arguments.
@BusinessWolf1
@BusinessWolf1 Жыл бұрын
This video helped me understand what object oriented is much better. Thank you. I still need a job tho, so I can't switch.
@marktellez3701
@marktellez3701 Жыл бұрын
When you have to debug something for two days to get to the state bug, you will get it. This just doesn’t happen in functional programming because the state is decoupled.
@mfpears
@mfpears Жыл бұрын
OOP is my least favorite part of Angular. Every once in a while, someone will suggest extending a class somewhere, but it doesn't take long for that pattern to disappear again, thankfully. The new inject functionality feels like more of a departure from OOP as well, which is awesome. But I would still like something more like Solid where it's a function that just runs once. Maybe the Angular team is working towards that direction. They had Ryan Carniato present his stuff to them somewhat recently. We'll see how that ends up influencing the future of Angular.
@danielstill5625
@danielstill5625 Жыл бұрын
Yeah Solid is bliss. Components are just functions that run once, basically a super enhanced version of Document.createElement(). I really hope Solid takes over, or other frameworks embrace it's model.
@bigmistqke
@bigmistqke Жыл бұрын
@@danielstill5625 i heard Vue is doing something similar to solid w vapor?
@TayambaMwanza
@TayambaMwanza Жыл бұрын
Source on Ryan meeting with angular team? That's interesting.
@mfpears
@mfpears Жыл бұрын
@@TayambaMwanza I don't know, but I would look for it on one of his Friday streams from the last couple of months during the "this week in JavaScript portion" It might not even be there, but that's probably where it is
@mfpears
@mfpears Жыл бұрын
@@TayambaMwanza if you find it, please let me know. I might make a video about it. And if I end up looking for it again, I'll comment here.
@jimiscott
@jimiscott Жыл бұрын
I watched the original and now I have watched this and I think it's fundamentally misguided. Below is my rebuttal, but as others have noted OO allows you to build very large, maintainable systems. Performance - Whilst a side note, this is actually addressed by the Flyweight pattern in GoF's Design Patterns. 'Some applications could benefit from using objects throughout their design, but niaive implementation would be prohibitively expensive'. Inheritance - As others have noted, use inheritance judiciously: allowing addins to inherit some key classes allows the addin to easily add/override the necessary functionality. Your statement of it's 2022 is....crap...you need to justify your statements. VB6 - Ask anyone who developed in VB6 and (COM nightmare excepting) they were extremely productive. This must be a result the programming paradigm was indeed better than procedural. I strongly doubt that a procedural language could have had the same properties/advantages: specifically garbage collection. Patterns, DI and TDD (or thereabouts) will produce better, more robust OO code. Not everything is about encapsulation - The Flyweight, the Visitor pattern (whilst trying to not bang on about patterns) both address encapsulation and where encapsulation may not be appropriate. It is not half arsed if you apply the/a pattern(s) correctly and think/architect good code. Messages - Not everything needs to directly reference other objects. There are ways to loosely couple objects....the Mediator or CQRS patterns for instance. The level of abstraction with these patterns can lead to indirection, but that is what is being asked. Object Sharing & Encapsulation - It is never explained what real-world scenario where objects are shared, and where multiple objects change the state of the shared object. Perhaps real-world example(s) may help to backup the thrust of the discussion. God Object/Object Hierarchy/Cross Cutting Concerns - Dependency Injection. Wrangling the Object Zoo - Really, I don't see what the complaint here is. This is not wrangling, but instead a change to requirements mandates a change to the object hierarchy. Some thought is often needed and indeed, desired. "All problems in computer science can be solved by another level of indirection" :) The discussion with the building and walls - Yes, poor architecture is poor architecture. You can do this with C you can do it with Eiffel. If you don't think and test your design before hand you will get into this mess. No Structure - No structure? You are literally referring to spaghetti code. My mind is now blown at this point. Global State - How much global state are we referring? In my experience we should be attempting to minimise global state. Brian keeps referring to god objects (and whilst I understand his point), he is actually referring to root objects...at the extreme other end, you could just stuff every variable into some loose global state (which is not desirable). Parameterisation - Use dependency injection / IoC. This also alleviates the complaints concerning cross-cutting-concerns (as they can be injected). Long Procedures * Can be difficult to test. * Can be difficult to understand. * Comments mean that you now need to update both the code AND the comments, of which only the former will be true 100% of the time. End.
@DerekWelton
@DerekWelton Жыл бұрын
I agree with you 100%. Maybe it's because I'm a dot net developer (not dot net framework that everyone likes to bash on, dot net core/Net6), but most of his points were just flat out wrong. It's like he was only looking at college level code that used OOP. I totally agree on his point that people do sometimes get caught up in abstracting too far, but this isn't a OOP problem. The part with stuffing all the code into a function is what did it to me.
@FADHsquared
@FADHsquared Жыл бұрын
I've read a very good comment on the original Brian Will video that Dependency injection simply makes the illusion of solving the problem you stated instead of solving it Also isn't it weird that all these "design patterns" surfaced because of OOP?
@cotneit
@cotneit Жыл бұрын
20:32 - The Man In The High Castle is the movie the map is from btw, great watch
@liquidotacita7027
@liquidotacita7027 Жыл бұрын
50:30 this is actually how c++ lambdas work
@simjans7633
@simjans7633 Жыл бұрын
Brian seems to talk about how OOP seeks to group related functions and data in the name of encapsulation. Another alternative to OOP would then be what lisps do with homoiconicity where data and functions are the same thing and everything is an expression. You would avoid the problem of how to group data and functions altogether because it's all data/functions.
@wolfgangschneider3743
@wolfgangschneider3743 Жыл бұрын
C++ lambdas can do what he was looking for (fine grained control over what parts of an anonymous functions environment are being captured while defaulting to none). Brilliant video of Brian, I couldn't agree more!
@mynameismichael123
@mynameismichael123 Жыл бұрын
This has been one of my favorite videos for a long time. Thanks for reacting. AbstractSingletonProxyFactoryBean
@JLarky
@JLarky Жыл бұрын
This video was so controversial at the time. Now that I spend most of my time in Elixir and React it feels like just stating the obvious facts :)
@BennyDeeDev
@BennyDeeDev Жыл бұрын
Code is Art, if you are trying to force a rigid structure to it, it always blows up.
@danvilela
@danvilela Жыл бұрын
Finally someones who says that code is art! I agree but didnt see this before
@vuufke4327
@vuufke4327 Жыл бұрын
OOP is an over-engineered solution that mostly does not achieve it's purpose, but there are good cases where using anything but OOP is just nuts
@tobiasnickel3750
@tobiasnickel3750 Жыл бұрын
I think the USE block is useful when you start coding with a question mark operator, and then find there is to much going on within one block. Today it is then needed to do the extra logic before the question mark operator, cluttering the function with more local state. But I also think this is a first world problem and I can get along without a use block.
@codenameirvin1590
@codenameirvin1590 Жыл бұрын
Agreed, Jonathan Blow is clearly a smart guy and right in a lot of the things he says. I also find his rants to just be generally funny. However, as you point out, there isn't anything prescriptive in his content. Although, his talk "Prevent the Collapse of Civilization" is one of my all-time favorites.
@thepaulcraft957
@thepaulcraft957 Жыл бұрын
I think he is mostly right, the only thing where I think he isn't right is the part about factories. I think there are use cases where factories a great
@Xania-js
@Xania-js Жыл бұрын
the 'use' block is some what comparable with the static local function in C#
@lawrencejob
@lawrencejob Жыл бұрын
“You shouldn’t use inheritance [because] it’s 2022” implies fashion rather than empirical basis
@DanKaschel
@DanKaschel Жыл бұрын
It doesn’t though. Like, if someone said, “you shouldn’t keep slaves because it’s 2022”, would you consider it a fashion position or merely an acknowledgement that, while people may have believed slavery was okay at one point, they no longer do (in the developed world, anyway)?
@hellofriend1128
@hellofriend1128 Жыл бұрын
@@DanKaschel bro are you comparing OOP to slaves?
@calebvear7381
@calebvear7381 Жыл бұрын
@@DanKaschel it isn’t an argument though. The fact that people predominantly think one thing now doesn’t make it correct. Back in 2000 they might have said you should do OOP because it’s 2000.
@deistormmods
@deistormmods Жыл бұрын
@@hellofriend1128 Ever heard of the word analogy?
@jscul
@jscul Жыл бұрын
It's an interesting idea, I wish you or him talked about nesting though at around 47:54. If you keep your functions like how it looks on the right side but also don't take out any code (even if non-reusable) your code will quickly become nested hell to work with. EDIT: nevermind, lol. Literally 2 seconds after I left the comment you start talking about it.
@zaviermiller8980
@zaviermiller8980 Жыл бұрын
i’ll take it as a good sign that i’ve watched this talk and have not heard of jonathon brow
@GameDevNerd
@GameDevNerd Жыл бұрын
These extremist anti-OOP ideas are easy for web developers to fall into. Go work on lower-level software and game development where you _need_ abstractions on top of things like graphics drivers or you need to build a game engine on top of multiple rendering APIs and you need it to still be fast. Sure, functional and "procedural" programming is great for web development and OOP feels like using an oxy-acetylene torch to light birthday candles to web devs. But when you need to cut steel you need that torch. Inheritance is _not_ "irrelevant", it's useful on a regular basis. We discourage _beginners_ and _junior_ devs from using it because they try to do it just because it exists and not because it makes sense. You inherit something when it shares a common ancestry. In a video game or simulation where you wanted to simulate all of nature you'd implement an _abstract_ parent class "Animal" for the animals, that implements all of the common features that all animals have (even if it's just a name, taxonomy and basic descriptors). More abstract classes like "Mammal" and "Reptile" can inherit that and implement their common class features. So down the line you can implement Dog, Cat, Deer, Squirrel, etc stemming from mammal and having their own taxonomic hierarchy. Lizards, snakes and turtles will have their own family tree. And I can have core systems in the simulation that will track pointers or references to all animals or certain groups or individual species of animals. I can add on more animals over time via inheritance and they work with all the core systems and only need their own specific features added. This is the concept of Liskov Substitution. These aren't "bandaids" on problems, this is just mastery of something that (while, admittedly, is not easy) is working the way the gods intended, lol. Encapsulation _is_ taken seriously. Abstractions _do_ simplify things in countless ways. Cross-cutting? What the hell are you using, Javascript or something? Lol has to be ... and you're _abusing_ inheritance and the OOP features rather than _using_ them if you think of a hierarchy this way and haven't learned how to use encapsulation, polymorphism, etc. If a "god object" is even part of your vocabulary or thought process with OOP then you don't get it yet, lol. Or he's just describing beginner/junior _spaghetti code_ that people tend to write in their first 1 to 3 years when they haven't mastered OOP. It's a very hard paradigm to master, I won't deny that, it kind of reflects the concepts of the real world where different things (like animals) share common features and lineage or things like rocks can be put into groups and classified. I abused the hell out of OOP concepts/features when I was starting my own learning path over 15 years ago. Now I see how elegant and beautiful it is when it's applied correctly. "Should a message send itself?" ... seriously? That's probably just an event, or something a simple observer pattern would handle. The real world isn't abstract? Then how do people understand what I'm talking about when I say "that building over there"? Because you understand an abstract idea of what a building is, even though buildings appear in a limitless variety of concrete forms. And you automatically understand the similarities between that building and a very different one, even though their form, function and the materials they're made from are entirely different. The problem comes when people who haven't mastered OOP concepts and probably don't know several OOP languages or have experience shipping things with those languages are trying to use it to invent abstractions for abstract things like components you're imagining for a website. There's no such thing as a "login manager" or a "message dispatcher", these are abstract ideas of responsibility you're making up and then trying to abstract again. The problem isn't the languages or the paradigms, it's your design and architecture ideas. If it's easier for you to do it with a functional language and that's fast enough then use that functional language you like. But don't come tell me how to write a flight simulation or a video game or an engine, especially if you've never done it, lol. I'm not here to say functional programming or his "procedural programming" ideas are bad. It's all about what works for the problems you solve and the things you create. Assembly languages seem horrible to most people, but when you're building a lower-level system like an OS or a device driver, assembly language can make parts of that development _very_ fast and easier in some places. And you'll probably use a lot of C for that, and have some C++ code above that to provide APIs with abstractions. If you've never done it then you won't get it. Paradigms aren't inherently "good" or "bad", it's about what solves your specific problems or helps you create the things you want to create in a way you're comfortable with and can deal with. This extremism and evangelistic attacking of other fields and paradigms is ridiculous and isn't useful in any way ... if you're a web developer then don't tell device driver programmers, OS devs, game devs or native app devs what language they should have to use just because you like it and don't understand their field. The same thing can easily work in reverse and I can attack Javascript and its frameworks and the fragmented nature of web tech stacks. But I'm not angry about you using something you're comfortable with and enjoy.
@scvnthorpe__
@scvnthorpe__ Жыл бұрын
You raise interesting points, but I would dispute inheritance - I prefer *composition*. For example, deriving dogs and cats from mammal is cool and all but sometimes mammals are cold-blooded, or they're aquatic instead of terrestrial or they shed some other trait basal to the clade. Dolphins and ichthyosaurs *derive* from ungulates and diapsid reptiles respectively, but have removed as well as changed/added similar traits such that they're more similar functionally to each other than to their ancestors - evolution doesn't really extend from ancestry without modification/loss in the way inheritance does. But evolution *does* broadly copy body plans or derived features in various combinations even across unrelated species in response to similar environmental pressures. So rather than having a base class of Animal where you can't promise it'll have legs or working eyes and having to write those explicitly into each subclass, you would implement your eyes, your leg setup or the fact you're warm-blooded as mixins and put those together to get your critter. That's just my take on it anyhow, and the kind of code you need for a CRUD app vs a live game environment are very different.
@GameDevNerd
@GameDevNerd Жыл бұрын
@@scvnthorpe__ I favor composition unless the _is a_ relationship is obvious and clear. Simulating all of nature and the animal kingdom is a really complex subject but it makes a good go-to example for OO logic at a certain scale. I would model that sort of thing with a strategy of both inheritance of _is a_ relationships and composition of components like legs ... legs have a child node "foot" which can have components like claws, if you want to get deep into the complexity. But in a video game or real-time simulation we wouldn't even get that deep into modeling classes for every single body part. But body parts would be like a component model and families of animals would draw from a "prefab" setup of certain components that have different properties. Composition usually does the job for most of your code, and rightfully so. But in many situations more complex object systems call for inheritance. Liskov Substitution is also really powerful in video game and simulation architecture and you can have systems that allow you to easily add things on with less code. My general rule of thumb for OOP is how do I make this code as clean, concise and clear as possible where it's going to work long-term without having to be rewritten.
@marcossidoruk8033
@marcossidoruk8033 Жыл бұрын
Bullshit, most graphics APIS are written in C and thus are purely procedural, they still provide abstractions sure but they treat data and functionality distinctly, thats like the whole Fing point of the video, if you are using this APIS to write OOP code you did that to yourself. And in fact, it seems that you never talked to a low level guy in your entire life, it is low level guys the ones that oppose OOP the most.
@GameDevNerd
@GameDevNerd Жыл бұрын
@@marcossidoruk8033 tell me you never used DirectX without telling me you never used it. Wouldn't be an issue if you weren't try to dispense "correction" on things you clearly don't understand with a hostile attitude. Graphics APIs are written with mixture of assembly language, C and C++ for the most part. And the lowest level parts of of graphics ecosystem where you find a lot of "pure" C and assembly language is actually handled at the device driver level. Most of the lower-level parts of a rendering API go into a HAL (hardware abstraction layer) that interacts mainly with the drivers and they add abstractions so that client code can interact with underlying hardware through it regardless of a specific model of CPU, GPU, etc. Bits and pieces of it are in assembly, done on a per-hardware basis, because not all platforms have the same architecture and can have different ways of accessing registers and memory, and you'll also have different mappings for reserved addresses, not to mention totally different sets of op codes which will have different mnemonics and binary values (and completely different extended instruction sets that may be supported only by certain members in a family of processors). Assembly makes it a lot easier to read/write directly to physical RAM but only if your code is running at Ring 0 and has that level of permission in the system, otherwise the OS will crash it so it can't wreak havoc. But when you install a runtime for DirectX or OpenGL it installs the correct version and parts that are going to work with your hardware and its device drivers typically supplied by the manufacturer (e.g., NVidia or AMD), and an abstraction layer sits _on top of_ that. And then there are more abstractions on top of that, building up the actual API exposed to client code through the libraries. They expose to userland programmers mainly through classic C header files that give you signatures of the things in the runtime libraries (like Windows DLLs that are consumed at runtime rather than linked into the build input like static .lib files). They avoid using "true" C++ and classes in the exposed parts of DirectX because they don't want to _force_ you to use C++ ... C++ code can happily work with C headers, as we all know, but not the other way around. Microsoft actually used a pretty novel approach for DirectX: instead of consuming true C++ classes/objects directly, which rely on C++ language features C simply doesn't support, they modeled a lot of the API through _COM interfaces_ (another form and layer of abstraction) that both languages can use. You're essentially calling free functions that are returning handles and pointers to COM interfaces that aren't treated like objects even if the underlying code Microsoft wrote behind the scenes does use them (you wouldn't even have a way to know, it's distributed in native binaries, closed source, and we just go by what small bits of information they give us about the underlying implementation). The COM interfaces of DirectX don't ever change once distributed so as not to break backward compatibility with existing code. So if they have to change things you just get a new version of the COM interfaces with a predictable naming convention like: IDXGIFactory, IDXGIFactory1, and so on ... they just add a number to the end of the original name to denote the interface version, and let you know if you need to migrate away from an older one. The beauty of it is that despite being a bit clunky and hard to understand, you can interact with it from basically any language that is COM-aware and you can also wrap the functionality of DirectX to be consumed in many other languages (depending on the language you may need a "middleman" layer, especially if you can't use pointers or cross the boundary of their domains). This is all _abstractions on top of abstractions on top of abstractions_ and abstraction is necessary to have APIs that are going to work across different platforms, especially when you start talking about things like OpenGL and Vulkan that are designed for other _operating systems_ as well as a varied and fragmented hardware ecosystem. The next layer of abstraction is left to you, as a developer of a 3D application, game, game engine or framework. And as a developer of modern engines or applications you're probably going to want it to be cross-platform and have the best possible experience on other operating systems and hardware. So unless you're targeting one specific API, you'll have more abstractions in your code to abstract away the underlying details of the rendering API so that they can be changed. Without having to rewrite your higher-level engine or application code. And, yes, we use abstractions and OOP architecture to accomplish this because people don't want to write games or 3D apps with C and assembly language, they want to use C++, C# or even scripting languages to implement their gameplay features and not have to worry about interacting with a D3D COM interface or a pointer to OpenGL resources. That would make cross-platform development nearly impossible like it was in the old days. What you consider "low-level" all depends on what field you work in and your perspective. To 99% of today's programmers, things like game engine development and rendering APIs seem very low-level and arcane. But to someone who develops system-level software like device drivers or Linux kernels, that seems very high-level and abstracted (you have extravagant luxuries in userland like virtual memory, lol). I've even met old school hardware gurus and assembly programmers who consider C a high-level language, and from _their_ perspective they are correct. But to a Python or Javascript programmer, C seems like a masochistic low-level language from the 7th layer of Hades, lol. Dunno where you get your information from but the whole world of modern programming is built on abstraction layers. We don't use punch cards and spindles of magnetic tape anymore, and low-level programmers aren't opposed to abstraction: they're actually _providing_ a lot of it so that we can build modern software ecosystems on top of it. I've done my fair share of lower-level programming, and I've spoken to and read books and articles by tons of other people in the field. There isn't any universal opposition to OOP or abstraction at all and most of them like creating good abstractions for people to actually use things to build with. It's become a lot less common to meet old guys who are hardcore assembly language Puritans, but there have been people like that every time the landscape changes, like going from punch cards and binary to these "high-level" assembly mnemonics and assemblers that spit out op codes for you automatically based on mappings, or going from pure assembly to this "high-level" language called C, then C++ and so on. There's always someone really conservative who hates the new ways, but they've had little influence because they would just halt progress in software engineering and tech if they had their way. Nope, most of the opposition to OOP is in the fields of web development and in functional programming. You have some really smart guys who go off the rails for functional programming and eventually make themselves unemployable and quite useless to any team because they're so absorbed in a fanatical Puritan philosophy of hating established OOP conventions and wanting to force everyone to do functional programming even when it doesn't make sense for a certain field or problem set. Thankfully, those people don't have much influence either. Anyone who builds their programming philosophy around hating something and wanting to force everyone to adopt _their_ ways is a rather useless programmer.
@marcossidoruk8033
@marcossidoruk8033 Жыл бұрын
@@GameDevNerd holy shit Someone can't understand basic English. I never claimed that APIS don't provide abstractions, I don't know why the hell you had to write a whole essay on that, looking for someone to validate what you learnt today? Want a reward or something? Seriously you just listed a bunch of field specific knowledge of yours (all that directX jazz) and a bunch of other common computer knowledge wich is completely irrelevant to the point, it seems like you are trying to look smart or something lol, you just look pathetic. I just said that the whole point of the video is that OOP and abstraction aren't the same thing at all, that it is possible to create abstractions without OOP (in fact, you have to be mentally deranged to think otherwise) and you somehow interpreted the exact opposite. Read carefully before wasting your time writing essays lol. And no I don't use DirectX, I don't like trash Microsoft software. Still I don't see how that is at all relevant, however judging by your inability to read and subsequently produce essays that have nothing to do with the original point I am not amazed. And no, low level Isn't relative, low level is systems programming or lower. Anything that has to manage the hardware directly and not through syscalls. Those guys oppose OOP, they could use OOP for writing logic, since besides all the hardware interaction there is a lot of logic in an OS, but they don't because it just doesn't work. For videogames it might because it is so much easier to write a videogame, but for actually hard stuff it is just not viable.
@Bruh-sp2bj
@Bruh-sp2bj Жыл бұрын
Yall know you can use oop with functional programming right?
@MrJoseklon
@MrJoseklon Жыл бұрын
Glad to see Brian Will being recognized
@grumpylibrarian
@grumpylibrarian Жыл бұрын
There is a language that uses the "use" syntax to explicitly import variables from the surrounding scope, and cannot use variables that aren't passed or "use"-d. The "use" variables are even copies by default, unless explicitly passed by reference. Unfortunately, this language is PHP. One could technically make a function without a closure scope in JavaScript, but it requires using the "Function" class, and evaluating the contents from a string. I have done this in extremely rare cases. It's certainly not practical for inline functions, which is where it would be most useful. Still, there is tangible benefit to where inline functions can only "pull from upwards." I like for any block I write to have "const" definitions at the top of the block, including IIFE arrow functions for scoping out any constants used to calculate a final value, and any branching / looping at the bottom of the block. As much as possible, a value is defined at the level it's used, making it easier to differentiate what will be used later from what will never be used again. "let" is an evil that rarely needs to show up. I'm also finding a lot of benefit in using generators and async generators to break up long, complicated nested looping into fewer indents. That breaks the consolidate-into-one-function pattern Brian mentions, but this actually does help make the code readable. Many of these pieces can be made reusable, too. Otherwise, if a routine is used in only one place, it gets inlined, and usually doesn't get a name.
@robbietorkelsonn8509
@robbietorkelsonn8509 Жыл бұрын
fun fact: procedure programming is the (almost) the last discovered programming paradigm, it is a catch all phrase for not having a programming paradigm at all. It came about when people were playing around with turbo pascal and QuickBASIC. almost the last because this one is actually the last: [Serializable]
@c4tubo
@c4tubo Жыл бұрын
This video is the first of two that have had the most impact on the way that I program.
@lesterdarke
@lesterdarke 6 ай бұрын
Watched this before and it's great watching it again. I have to work with a monolithic codebase for data processing and there's loads of it that's written in OOO principles but then non-ooo developers have worked with it since so we have the worst of both worlds and this really made me understand better what my issue with ooo stuff is... spendding my life tracing code using "goto definition" to go up and down the dependency tree for something that procedural code would just make obvious. Albeit there's also just code that sends stuff to dynamo db driven task queues where suddenly you don't have immediate access to what happens next..... Good to revist though some really nice principles that he outlines that I potentially miss. I wonder if there's any good literature on procedural code that embraces this kinda of nuance of no hard and fast rules but these are things to think about.
@JLarky
@JLarky Жыл бұрын
20:51 it is interesting to bring up the example of Python, because at the time it seemed that Ruby would be more successful than Python exactly because Ruby was more object oriented than Python :) but it didn't pan out :)
@CaptainWumbo
@CaptainWumbo Жыл бұрын
ruby (and especially rails) served a lot of businesses very well. I don't know much outside of data science that uses python, and though data science has blown up a bit I have found supporting python projects for data scientists to be painful. Then again I also find corporate style ruby really painful :') There's no paradigm or language that can't be destroyed with design by committee. imo most people are happiest on small teams where they are trusted with a lot of design, and everyone feels oppressed trying to fit within an existing hobbled together immovable architecture. And now we get these "influencers" having their cake and eating it too, inflating their egos when they're already working in easier systems with smaller problems (human relations wise and technical). I'm jealous af to go back to that gravy train lol
@danvilela
@danvilela Жыл бұрын
@@CaptainWumbo i miss small teams 😢
@MarthinusBosman
@MarthinusBosman Жыл бұрын
Brian's video just needs some example code to land the concepts
@AlexanderSuraphel
@AlexanderSuraphel Жыл бұрын
"When we pollute our code with generic entities like managers and factories and services, we are not really making anything easier to understand. We're just putting a happy face on the underlying abstract business."
@scvnthorpe__
@scvnthorpe__ Жыл бұрын
FWIW I'm horrendously addicted to splitting functions into sub-functions if it becomes at all harsh to read. Also, I feel like for something like subject.verb(object) the concept of infixing in Haskell could be applied. Maybe.
@scvnthorpe__
@scvnthorpe__ Жыл бұрын
(This would also help w/ the procedural autocompletion, and type hinting on the first arg could roughly map to some data type without strictly marrying to a class.)
@minikame2272
@minikame2272 Жыл бұрын
Okay so my more serious comment would have to be that this is probably the underlying issue that's been plaguing the development of what I thought would be a relatively simple SaaS web app. I had the end user's requirements mapped out from the start, but never thoroughly considered my own developer requirements. It never occurred to me that I wouldn't know exactly what would be needed X weeks from now unless I'd already done it, and after spending months trying to do everything 'properly' I found myself constantly modifying and exposing new portions of convoluted class constructors I'd written previously in pursuit of code reuse. Where was the fucking code reuse? It was so forced. I was trying to save myself time and in the process incurred the painful task of rewriting and modifying the same stuff over and over again, every time I needed to do something that was largely the same but a bit different. About a month ago I said 'screw it just write it badly and quickly' and development has been going blisteringly fast since then and... honestly the codebase isn't even the hellhole I thought it would be. And I'm not breaking things apart each time my requirements change anymore, the code that was there before worked before and works now, I just create new functions and call existing functions if using their output would speed things up at all. But the existing ones don't change. New ones are added. Everything carries on working. Now I'm here scratching my head about why I'm forcing an OOP language to cosplay Pascal. And honestly, I thought it was just my inexperience as a dev. I didn't know these issues ran the full gamut of talent. It's a relief, but also really frustrating.
@distinguishedmoments2277
@distinguishedmoments2277 Жыл бұрын
I love this video, makes a lot of sence. It's also worth noticing that depending on the scale of your software and the team that works on it, problems are going to have to have significantly more constricted ways of being solved, thus not always giving the developer the same freedom to develop than one has in a smaller project
@KangJangkrik
@KangJangkrik Жыл бұрын
"Declare functional components as possible, OOP confuses both human and machine" - React Developers
@uddinrokib7
@uddinrokib7 Жыл бұрын
Yeah. And then use 10 useState, 10 useEffect in the function and make it a mess.
@KangJangkrik
@KangJangkrik Жыл бұрын
@@uddinrokib7 for what? 20 useState still readable, and mostly 1 useEffect is enough except you're going to ruin ur app on purpose
@fallingintime
@fallingintime Жыл бұрын
@@KangJangkrik won't this impact performance (using multiple useStates) . I always assumed that many deps in a useEffect hook is a bad idea
@CalebStephensPlaysPiano
@CalebStephensPlaysPiano Жыл бұрын
I came from Java and once I started learning functional JavaScript I was sold. Never going back. Now I am building a MERN app to help solidify my JavaScript. Any good suggestions for resources to learn procedural/functional code is welcome!
@ftwtf
@ftwtf Жыл бұрын
java is very functional dude, much better and faster than js
@BbB-vr9uh
@BbB-vr9uh Жыл бұрын
Vast majority of our backend is in Java at my job and its pretty rough.
@robfielding8566
@robfielding8566 9 ай бұрын
Go basically does this right. You do procedural programming. But if you want messages being passed between state machines; at least make the messages just (preferably immutable) structures. The UML would be so much more useful if it more tightly tied together state machines (actors) and their messaging. When you are dealing with hardware; you can only make them send messages amongst themselves. It's the same for machines across a network.
@steveorevo
@steveorevo 8 ай бұрын
"A pure function is a function with no side effects... you give it something, you get back something." - Welcome to flow programming... aka spaghetti.
@Blaisem
@Blaisem 5 ай бұрын
50:30 if I'm understanding him correctly, PowerShell actually provides this functionality for multi-threaded tasks. Any time a new thread is created, it runs in a new session, which means its state is empty except for default variables. This means the enclosing scope won't be shared with the new thread. However, you can explicitly inject local variables from the enclosing scope via the `using:` scope modifier, e.g., `$using:a; $using:b`. These are passed as values and not as references, so the new scope can do whatever it wants to these variables without impacting the enclosing scope in any way. In theory, you would be able to achieve what he's talking about with something like `Start-ThreadJob -Scriptblock { $a = $using:a; $b = $using:b ... } | Wait-Job`. "Start-ThreadJob" runs a task in another session on another thread; "ScriptBlock" is the PowerShell term for an anonymous function (the parser identifies standalone code enclosed in braces as an anonymous function), so you are passing this anonymous function to the new thread state to run; and piping to "Wait-Job" forces it to wait on the result rather than proceed asynchronously. You could also define the scriptblock code at the top of the procedural entrypoint like he demonstrated in another slide, e.g., $scriptblock1 = { doCode; return value }, and pass that along later: `$result = Start-ThreadJob -Scriptblock $scriptblock1 | Wait-Job | Receive-Job`. The piping is verbose, but this would be trivial to consolidate into a wrapper calling function, so that you end up with `$result = Invoke-Function $scriptblock1`. And if we want to be more rigorous, there are optionally additional bells and whistles available. We can be more explicit in our intentions rather than sliding in state via `$using:` but specifying the shared state as explicit parameters. You would begin by defining the scriptblock with a full-fledged `Param` block to receive your input parameters (and open up some optional declarative attributes shown below): $sb1 = { param ( [ValidateNotNullOrEmpty()] [string]$a, [ValidateSet(0,1,2)] [int]$status, [Parameter(Mandatory)] [string]$required ) doCode return value } and invoke it with a more explicit syntax of passing the local state via a parameter: `$result = Invoke-Function -ScriptBlock $sb1 -ArgumentList 'hello', 2, 'world'`. You could run sequential functions with isolated scopes in this fashion, where the only visible variables from the enclosing scope are specified via `$using:` or via the `-ArgumentList` parameter into a param block in the anonymous function.
@jonathandsouza7592
@jonathandsouza7592 Жыл бұрын
If inheritance is irrelevant is Object composition the way to go?
@sidharthcs2110
@sidharthcs2110 2 ай бұрын
I worked as a webdev . OOPS is something I've only did at University. I honestly don't understand it's concepts because the problems I was solving as a web developer never needed an OOPS approach. I was working in Node Js , function were the only thing I wrote.
@Burgo361
@Burgo361 5 ай бұрын
I have not only seen this talk I've already watched multiple people react to it lol
@SimGunther
@SimGunther Жыл бұрын
Smalltalk and Sketchpad were the closest to getting OOP correct, but that doesn't mean we shouldn't use concepts from Simula-like languages such as data hiding and making array of structures (if we access more than one or two fields in a struct). At least modules in Modula and Smalltalk's OOP to some extent _tried_ to be a solution to a problem. I have no idea what class oriented programming tried to solved whatsoever. The biggest con about OOP is that it's so easy to focus on the wrong parts of high level design like using UML diagrams to model classes with real life analogies as a false blueprint of programming. Just focus on the data along with its transformations/accesses and what you need "calculated" or assumed. That'll make the difference between maintaining big arrays of indices/types separately and wasting 5GB compiling the compiler (true story for Zig compiler development) because OOP was such a big priority for the higher ups. Now we settled that debate, let's actually move away from the Von Neumann architecture that's plagued CPU design for so long and create something that's not Harvard architecture because we know that waiting for main memory is either an unsolved or neglected problem because no one wants to admit that John wasn't right about all the computer things...
@HenrikVendelbo
@HenrikVendelbo Жыл бұрын
Abstraction bigger than functions is a program aka process. The original OOP was actually modeled on cells, so much more a lean process than the crap we call OOP today
@matswessling6600
@matswessling6600 7 ай бұрын
there are perfectly good uses of inheritance.
@jearsh
@jearsh 5 ай бұрын
is there any context around the "oreos are overpowered" statement in the chat? 5:44
@Gahlfe123
@Gahlfe123 Жыл бұрын
Learning coding for the first time in java with oop was a mistake in my opinion. Being forced to that style didn't give me a chance to understand cs as a whole. Would take a couple more classes until I understood why oop was messing me up
@fadhilh3931
@fadhilh3931 Жыл бұрын
True that, I hate programming because of Java in my beginning journey as programmer
@awwastor
@awwastor Жыл бұрын
So, I’d argue all programs need side effects. Otherwise, they don’t do anything, because printing to stdout is a side effect and so is opening a window or writing to a file. But not all functions need side effects. So, split your code into functions and try making as many of them pure, and then compose the pure functions with non pure ones into a program.
@zacharychristy8928
@zacharychristy8928 Жыл бұрын
Here's a lemma to add to that: any function that returns void and has no mutable input parameters must ALSO have side effects for the same reason. If it didn't, then the function can't do anything.
@DanielAbernathy
@DanielAbernathy Жыл бұрын
Heh - PHP's anonymous functions don't have access to their outside scope by default. Didn't think I'd ever see someone pining for a feature that PHP has.
@evandrofilipe1526
@evandrofilipe1526 Жыл бұрын
if you close your eyes he sounds like lumpy space princess
@ddomingo
@ddomingo Жыл бұрын
I actually like Java. It’s not my favorite, but I like what it brings to the table. I’ve had great dev experience with Java and have been lucky enough to work in wonderfully architected Java services. All OOP obviously. You end up appreciating the verbosity.
@T1Oracle
@T1Oracle Жыл бұрын
There's a lot of bad Java out there, including stuff from the standard library. This probably the source of a large amount of misunderstand about OOP.
@05xpeter
@05xpeter 7 ай бұрын
Developers can make amazing Java code if the get the architecture right from the start. But if they did it in a proceduel style it would be just as nice. Average developers will make shitty Java code, while if they made it procedual it would probably be decent. Point is that it takes allot for the stars to align to produce good Java code.
@ci6516
@ci6516 6 ай бұрын
Funny how no one can even show me the difference
@TommyLikeTom
@TommyLikeTom 4 ай бұрын
It's such a strange thing to say because everything is influenced by OOP. Obviously it's not good to create unnecessary relationships but it's obviously a useful tool. Look at the game Minecraft, everything is a block or an entity. It's smart, and it seems utterly unavoidable
@____uncompetative
@____uncompetative 4 ай бұрын
You can see nouns or you can see verbs or if you really get enlightened you can see the value in prepositions and relations.
@JeyPeyy
@JeyPeyy Жыл бұрын
Incredible, I always forget that it's *current year*
@EvanBoldt
@EvanBoldt 6 ай бұрын
15:58 Free is the understated carrot of appeal on the stick. Even NetBeans and Eclipse was free. Visual Studio licenses were hundreds of dollars. In Java the IDEs were free, and the programs you made were cross platform which was also almost unheard of at the time.
@paulsalele3844
@paulsalele3844 Жыл бұрын
Great content Theo!!
@sophiehaefner2908
@sophiehaefner2908 Жыл бұрын
44:35 / 44:15 Those are effects, not side effects. It depends on the project, of course, but I wouldn’t even say most code requires side effects. It’s really just the program output, and even in real-time applications, this isn’t usually where the majority of the work is.
Your Goals Kinda Suck - LEVEL UP As A Developer
34:40
Theo - t3․gg
Рет қаралды 140 М.
Teaching NextJS To Primeagen
1:19:51
Theo - t3․gg
Рет қаралды 227 М.
We Got Expelled From Scholl After This...
00:10
Jojo Sim
Рет қаралды 42 МЛН
1 класс vs 11 класс  (игрушка)
00:30
БЕРТ
Рет қаралды 3,7 МЛН
Купили айфон для собачки #shorts #iribaby
00:31
Китайка и Пчелка 4 серия😂😆
00:19
KITAYKA
Рет қаралды 3,7 МЛН
Object Oriented Programming is Good | Prime Reacts
31:30
ThePrimeTime
Рет қаралды 286 М.
Did I Pick The Right Database???
1:07:48
Theo - t3․gg
Рет қаралды 206 М.
You dont know OOP
50:48
ThePrimeTime
Рет қаралды 282 М.
My Favorite Language Isn't TypeScript - An Interview w/ Jose Valim
2:34:31
Ditch Your Favorite Programming Paradigm | Prime Reacts
16:02
ThePrimeTime
Рет қаралды 116 М.
Object Oriented Programming is not what I thought - Talk by Anjana Vakil
38:51
`const` was a mistake
31:50
Theo - t3․gg
Рет қаралды 111 М.
You Might Be Using Typescript Wrong...
15:32
Theo - t3․gg
Рет қаралды 193 М.
iPhone 15 Pro vs Samsung s24🤣 #shorts
0:10
Tech Tonics
Рет қаралды 14 МЛН
i love you subscriber ♥️ #iphone #iphonefold #shortvideo
0:14
Si pamerR
Рет қаралды 3,4 МЛН
Нашел еще 70+ нововведений в iOS 18!
11:04
Iphone or nokia
0:15
rishton vines😇
Рет қаралды 1,8 МЛН
wireless switch without wires part 6
0:49
DailyTech
Рет қаралды 4,4 МЛН