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

Sdílet
Vložit
  • čas přidán 17. 07. 2022
  • 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
  • Věda a technologie

Komentáře • 557

  • @turdsalami
    @turdsalami Před rokem +199

    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 Před rokem +14

      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 Před 11 měsíci +6

      Probably simply confirmation bias.

    • @h0ph1p13
      @h0ph1p13 Před 9 měsíci +2

      @@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 Před 8 měsíci +3

      php is the best

    • @b_delta9725
      @b_delta9725 Před 5 měsíci +1

      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 Před rokem +164

    "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 Před rokem +15

      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 Před rokem +12

      @@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 Před rokem +6

      "single responsibility" they said

    • @salluzziluca
      @salluzziluca Před rokem +8

      This can be solved with a UML diagram... but all my homies hate UML diagram

    • @noahfletcher3019
      @noahfletcher3019 Před rokem +4

      @@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 Před rokem +490

    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 Před rokem +20

      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 Před rokem +21

      i love that i miss my wife in the end.

    • @kibe2134
      @kibe2134 Před rokem +44

      I miss your wife too.

    • @DavidWoodMusic
      @DavidWoodMusic Před rokem +27

      @@sortof3337 She was just at Target when I was writing this.
      She is home now but she wants a divorce.

    • @vioricasuper4127
      @vioricasuper4127 Před rokem +2

      @@DavidWoodMusic Sorry bro

  • @Mentioum
    @Mentioum Před rokem +32

    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 Před rokem +1

      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 Před 3 dny

      I think you are missing the point. A bunch of types that act as an interface between library and user code is not OOP.

  • @spacey_sooty
    @spacey_sooty Před 7 měsíci +6

    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.

  • @ahmadkhatib3117
    @ahmadkhatib3117 Před rokem +12

    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.

  • @bjornbeishline6619
    @bjornbeishline6619 Před rokem +153

    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 Před rokem +17

      It's even funnier when they say that object oriented means easier to understand

    • @vd3598
      @vd3598 Před rokem +13

      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 Před rokem +2

      @@ac130kz Easier to understand. Better.

    • @NateLevin
      @NateLevin Před rokem +9

      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 Před rokem +2

      class OrganizationService extends CRUDService

  • @travism70
    @travism70 Před rokem +17

    Functional core, imperative shell was the thing to finally make pure functions/functional programming click for me. Wish it was brought up more.

  • @patchr6288
    @patchr6288 Před rokem +8

    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 Před rokem +2

      Thank you for sharing this. I have screen grabbed your comment.

    • @sacredgeometry
      @sacredgeometry Před rokem +1

      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.

  • @bartech101
    @bartech101 Před rokem +43

    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 Před rokem

      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 Před rokem

      @@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 Před rokem

      @@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 Před rokem +1

      @@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 Před rokem

      @@bartech101 ah ok yes! Have you found a good way to communicate they're not really intended to be used on their own?

  • @9SMTM6
    @9SMTM6 Před rokem +33

    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 Před rokem +4

      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 Před rokem +1

      @@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 Před rokem

      @@9SMTM6 I would expect that one way data flow fits very well with rust, but I've never used react

    • @redpepper74
      @redpepper74 Před rokem

      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 Před rokem +1

      @@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

  • @fededevi1985
    @fededevi1985 Před rokem +16

    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 Před rokem +3

      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 Před rokem +1

      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)?

  • @brandonj5557
    @brandonj5557 Před rokem +5

    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

  • @rogerdinhelm4671
    @rogerdinhelm4671 Před rokem +13

    >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 Před rokem +2

      >>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 Před rokem +2

      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.

  • @istasi5201
    @istasi5201 Před rokem +94

    OOP is not bad, whats bad is OOP being used as a hammer and everything is a nail.

    • @numeritos1799
      @numeritos1799 Před rokem +21

      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 Před rokem +5

      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 Před rokem +3

      ​@@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 Před rokem +2

      If instrument encourages people to use it in hammer-nail manner, it is enough to consider it bad.

    • @numeritos1799
      @numeritos1799 Před rokem +6

      @@Acid31337 OOP is a programming paradigm, how does it encourage anything?

  • @marna_li
    @marna_li Před rokem +20

    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 Před rokem +2

      He’s very explicit that he intends to discredit it as an approach, point blank

  • @VitalijMik
    @VitalijMik Před rokem +8

    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 Před měsícem

      Php is somehow underrated even though it's the most used language out there in web

  • @astartup
    @astartup Před rokem +1

    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.

  • @careymcmanus
    @careymcmanus Před rokem +15

    My Favourite that I didn't really get until I had a year of experience working on legacy OOP code is that abstraction makes it really hard to understand. I mostly program in c# at but also write a lot of python which I almost entirely write in a procedural manner. I want types not classes. The thing that I hate about OOP is that it makes unit testing really hard because when they get even slightly complex you have to pass so much irrelevant stuff just to get your test to pass.

    • @invictuz4803
      @invictuz4803 Před rokem

      Great example, that makes me feel better as I felt the same way when I was learning unit testing in C# for work.

    • @DanKaschel
      @DanKaschel Před rokem +14

      99% of complaints about OOP are about how bad code is bad.

    • @DanKaschel
      @DanKaschel Před rokem +4

      @@invictuz4803 for the record, that's because of your teacher. There's nothing fundamentally easier about testing in Python. And if your testing is complex, the tooling and syntax support is vastly superior in C#.

    • @zacharychristy8928
      @zacharychristy8928 Před rokem +4

      ​@@DanKaschel This has been 100% my experience. OOP doesn't shine with little 'toy' examples like the ones you have to use in lectures or instructional videos. It works well in massive interconnected code bases, managing complex, interdependent areas of code with high amounts of re-use, so every 'toy' example makes it look overcomplicated when it's really a godsend in certain use cases.
      I'd love to see Brian Will try to make a large game in Unity, or a complex desktop application this way.

    • @abgvedr
      @abgvedr Před rokem +1

      @@zacharychristy8928 Im with you fellas. Also he talks so much about oop this and oop that, but have he even analyse any alternatives, and all the pros and cons on many levels of complexity? I think not.

  • @kippers12isOG
    @kippers12isOG Před rokem +2

    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.

  • @tomasruzicka7161
    @tomasruzicka7161 Před rokem +2

    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 Před rokem

    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.

  • @RobEdwards369
    @RobEdwards369 Před 10 měsíci +2

    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 Před 4 měsíci +1

      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.

  • @BalintCsala
    @BalintCsala Před rokem +2

    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.

  • @awwastor
    @awwastor Před rokem

    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 Před rokem

      The C++ lambda is really neat for this, since any capture has to be explicitly declared

  • @lawrencejob
    @lawrencejob Před rokem +10

    “You shouldn’t use inheritance [because] it’s 2022” implies fashion rather than empirical basis

    • @DanKaschel
      @DanKaschel Před rokem +6

      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 Před rokem +4

      @@DanKaschel bro are you comparing OOP to slaves?

    • @calebvear7381
      @calebvear7381 Před rokem +2

      @@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 Před rokem +1

      @@hellofriend1128 Ever heard of the word analogy?

  • @alexischicoine2072
    @alexischicoine2072 Před rokem +1

    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 Před rokem +1

      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.

  • @zacharychristy8928
    @zacharychristy8928 Před rokem +47

    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 Před rokem

      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 Před rokem +8

      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 Před rokem +2

      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 Před rokem +1

      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 Před 11 měsíci

      @@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.

  • @jon_escamilla_
    @jon_escamilla_ Před rokem

    After seeing your wall of nice headphones; what keeps you or has you using the SHP9500s?

  • @JamesTsividis
    @JamesTsividis Před rokem +1

    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.

  • @jameender
    @jameender Před rokem +47

    It's really refreshing to see people talk about actual problems of OOP

    • @rogerdinhelm4671
      @rogerdinhelm4671 Před rokem +11

      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.

  • @empresagabriel
    @empresagabriel Před rokem +3

    "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

  • @dl0.0lb
    @dl0.0lb Před rokem

    Saw the thumbnail pop up and immediately was excited for your viewers, this video is such a banger.

  • @CottidaeSEA
    @CottidaeSEA Před rokem +1

    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.

  • @asdqwe4427
    @asdqwe4427 Před rokem +1

    I remember listening to his takes on OOP years ago when learning functional programming concepts.

  • @debasishraychawdhuri
    @debasishraychawdhuri Před 10 měsíci

    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.

  • @robnauticus
    @robnauticus Před rokem

    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! 😁

  • @lunedefroid8817
    @lunedefroid8817 Před rokem +1

    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

  • @sidharthcs2110
    @sidharthcs2110 Před 2 měsíci

    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.

  • @AlexanderSuraphel
    @AlexanderSuraphel Před rokem +23

    "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."

  • @TommyLikeTom
    @TommyLikeTom Před 3 měsíci +1

    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 Před 3 měsíci

      You can see nouns or you can see verbs or if you really get enlightened you can see the value in prepositions and relations.

  • @mfpears
    @mfpears Před rokem +4

    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 Před rokem +1

      Not to mention making it more testable, explicitly separates scope, and doesn't rely on "section comments" which are pointless.

  • @ddomingo
    @ddomingo Před rokem +20

    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 Před rokem +5

      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 Před 6 měsíci

      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 Před 6 měsíci

      Funny how no one can even show me the difference

  • @grumpylibrarian
    @grumpylibrarian Před rokem +2

    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.

  • @dHue_52
    @dHue_52 Před rokem +2

    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.

  • @phil-l-tech
    @phil-l-tech Před rokem +6

    I’ve been writing TS projects, NodeJS, front end for 6-7 years without a single Class (no new Class()), only functions, types and good files organization
    My code is clear, easy to understand, easy to tests, has clear abstraction levels
    Over-engineered oop code bases are none of that

    • @igorswies5913
      @igorswies5913 Před rokem +2

      you can write OOP without classes, just using factory factions utilising closures

  • @liquidotacita7027
    @liquidotacita7027 Před rokem +2

    50:30 this is actually how c++ lambdas work

  • @merkelizer9940
    @merkelizer9940 Před rokem

    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.

  • @marktellez3701
    @marktellez3701 Před rokem +2

    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 Před rokem +8

    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 Před rokem +2

      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 Před rokem

      @@danielstill5625 i heard Vue is doing something similar to solid w vapor?

    • @TayambaMwanza
      @TayambaMwanza Před rokem +1

      Source on Ryan meeting with angular team? That's interesting.

    • @mfpears
      @mfpears Před rokem +1

      @@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 Před rokem +1

      @@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.

  • @aidanbrumsickle
    @aidanbrumsickle Před rokem

    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.

  • @GameDevNerd
    @GameDevNerd Před rokem +52

    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__ Před rokem +3

      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 Před rokem +4

      @@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 Před rokem +6

      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 Před rokem +10

      @@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 Před rokem

      @@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.

  • @mattstyles4283
    @mattstyles4283 Před rokem +18

    Interesting video, but hating OOP only really applies to development where it just gets in the way. When you're working on a base with 1 million+ lines of code, you really can't go without some sort of encapsulation to break down state into smaller pieces.

    • @paulhamrick3943
      @paulhamrick3943 Před rokem +6

      But aren't there languages that just use "modules" or "namespaces" in order to put functions into categories that have names?

  • @stuff3219
    @stuff3219 Před rokem +1

    At several times he mentions the value of classes, thus destroying his primary thesis (OOP is evil). It should be called "OOP can be easily misused", which I think everyone would agree with.
    Also, his idea about code completion working as well with purely functional style??? Heh yeah no. Try working with a huge 3rd party api (Solidworks comes to my mind); The class structure is the only thing that makes it usable. Would be absolutely unworkable without it.
    Bottom line is OOP has it's place, but can be abused, just like every other style.

  • @vuufke4327
    @vuufke4327 Před rokem +1

    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

  • @GAoctavio
    @GAoctavio Před 9 měsíci

    Brian has a few more videos on OOP. I really like the examples one cause it shows how convoluted some "OOP solutions" can be

  • @codenameirvin1590
    @codenameirvin1590 Před rokem +1

    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.

  • @mynameismichael123
    @mynameismichael123 Před rokem +6

    This has been one of my favorite videos for a long time. Thanks for reacting.
    AbstractSingletonProxyFactoryBean

  • @awwastor
    @awwastor Před rokem +2

    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 Před rokem

      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.

  • @BusinessWolf1
    @BusinessWolf1 Před rokem

    This video helped me understand what object oriented is much better. Thank you. I still need a job tho, so I can't switch.

  • @JLarky
    @JLarky Před rokem +5

    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 :)

  • @TizzyT455
    @TizzyT455 Před rokem +1

    I feel like the people who agree with this are web developers who have no business even giving an opinion and the people who disagree with this are people who have actually developed large complex software. Those who champion pure functions and complain about state are probably the same ones who will tell you they like programming but didn't like or do well in computer science but what do I know... I only have a degree for telecommunications.

  • @simjans7633
    @simjans7633 Před rokem

    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.

  • @fiveljones2340
    @fiveljones2340 Před rokem +1

    "There's no reason to use inheritance, it's 2022"
    Godot: hold my beer

  • @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!

  • @tobiasnickel3750
    @tobiasnickel3750 Před rokem

    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.

  • @Bruh-sp2bj
    @Bruh-sp2bj Před rokem +3

    Yall know you can use oop with functional programming right?

  • @YTCrazytieguy
    @YTCrazytieguy Před rokem

    an abstraction that is bigger than a function and a data type can also be a module

  • @BennyDeeDev
    @BennyDeeDev Před rokem +2

    Code is Art, if you are trying to force a rigid structure to it, it always blows up.

    • @danvilela
      @danvilela Před rokem +1

      Finally someones who says that code is art! I agree but didnt see this before

  • @neeeeeck9005
    @neeeeeck9005 Před rokem +1

    "You can largely autocomplete your way through most of the usage" Someone on: 20:03 in chat "Me all day: ctrl-space enter enter enter enter" :D :D :D Legendary joke

  • @robbietorkelsonn8509
    @robbietorkelsonn8509 Před rokem

    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]

  • @lesterdarke
    @lesterdarke Před 5 měsíci

    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 Před rokem +2

    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 Před rokem +1

      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 Před rokem +1

      @@CaptainWumbo i miss small teams 😢

  • @minikame2272
    @minikame2272 Před rokem +2

    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.

  • @jimiscott
    @jimiscott Před rokem +12

    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 Před rokem

      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 Před rokem +1

      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?

  • @Gahlfe123
    @Gahlfe123 Před rokem +10

    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 Před rokem

      True that, I hate programming because of Java in my beginning journey as programmer

  • @jscul
    @jscul Před rokem

    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.

  • @KangJangkrik
    @KangJangkrik Před rokem +3

    "Declare functional components as possible, OOP confuses both human and machine"
    - React Developers

    • @uddinrokib7
      @uddinrokib7 Před rokem +1

      Yeah. And then use 10 useState, 10 useEffect in the function and make it a mess.

    • @KangJangkrik
      @KangJangkrik Před rokem

      @@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 Před rokem +1

      @@KangJangkrik won't this impact performance (using multiple useStates) . I always assumed that many deps in a useEffect hook is a bad idea

  • @cotneit
    @cotneit Před rokem

    20:32 - The Man In The High Castle is the movie the map is from btw, great watch

  • @thepaulcraft957
    @thepaulcraft957 Před rokem +2

    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

  • @DoctorSoulis
    @DoctorSoulis Před rokem

    So I should learn C++/C# (I want to learn game dev)? :c

    • @DoctorSoulis
      @DoctorSoulis Před rokem

      @@3_smh_3 Ty for the clarification man :D

    • @zacharychristy8928
      @zacharychristy8928 Před rokem +1

      Depends what you want to do! If you want to make actual games, C# is a good bet. It's got first-class support in Unity (and Godot's is pretty good). C++ is good if you want to work on engines themselves, or make games from complete scratch (just know that will take a LOT more work. Don't believe Jon Blow or Casey M when they tell you it's easier. It's not.)
      C# can also be used with the XNA framework if you want to take a lightweight approach. Plus it's got first-class functions and LINQ queries so you can make things as functional as you want if you really hate OOP.

  • @NeadjAWind
    @NeadjAWind Před rokem +43

    During an interview for a front end engineer role (React was the stack), I was asked by an Engineering Manager if I follow SOLID principles while reviewing PRs.
    I explained how I don’t think most of these apply to how you’d write a React codebase (even for a JS codebase overall I would argue as it’s prototype based instead of class based OOP) and he seemed disappointed.
    Didn’t get the job but I think it’s for the best, OOP brain rot is real 😅

    • @ShitIndie
      @ShitIndie Před rokem +6

      I got asked exactly the same with React and JS. Even our answers were the same.... and the outcome 🤣.
      I think it's for the best!

    • @danvilela
      @danvilela Před rokem

      For me the same! Lol then they said you can use solid even in html which is stupid. Didnt got the job thank god

  • @FunctionGermany
    @FunctionGermany Před rokem +1

    code can be without side effects, but programs without side effects are by definition useless because any I/O whatsoever is a side-effect.

  • @BinaryReader
    @BinaryReader Před rokem +12

    Brian's video is opinionated, but he's just wrong, or worse...wrong by omission. OOP is less about state encapsulation (although it's typically taught this way) and more about messaging, dependency injection and polymorphism (which in fairness he does briefly touch on). These concepts are fundamental and ONLY OOP patterns try to formally address them and where other paradigms don't even try (leaving the developer to fumble something together while trying to convince themselves they never needed OOP)
    I always cringe when you get these naive young programmers pushing anti OOP sentiment without properly understanding why OOP exists. I've worked with developers like this that would rather write messy functions everywhere than organize related methods into a class. I'm not adverse to Proceedural or Functional (being fairly invested in Haskell currently), but I just won't work people in positions of influence who think OOP is bad (especially when you see the crap code they're writing)
    For what it's worth, anti OOP sentiment tends to originate from lack of insight building large, organized maintainable systems.
    Also, T3 is bullshit marketing. Those 3 T's are not the only solutions that exist, and strict validation at IO boundaries should not be some revelation. It weirds me out that it is....

    • @ruyvieira104
      @ruyvieira104 Před rokem +1

      Why would you use a class as a namespace? It makes no sense

    • @BinaryReader
      @BinaryReader Před rokem

      @@ruyvieira104 ... why do you think it makes no sense?

    • @ewertonls_
      @ewertonls_ Před rokem

      @@ruyvieira104 why do you think it makes no sense?

    • @ruyvieira104
      @ruyvieira104 Před rokem

      @@BinaryReader defeats the purpose of OOP.

    • @BinaryReader
      @BinaryReader Před rokem

      @@ruyvieira104 what defeats the purpose of OOP?

  • @Blaisem
    @Blaisem Před 5 měsíci

    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.

  • @dedicatedserver8214
    @dedicatedserver8214 Před měsícem

    48:15 If you're going to be defining an inner function to get the scoping benefits, smaller surface area, and be able to use early returns so you don't move too far from the left margin, why not just move the function out and private it at that point?
    Even if its messily ordered anyone can ctrl + click on the name and instantly jump to the definition in modern IDEs and hit the back arrow on their mouse to go back.

  • @SergiobgEngineer
    @SergiobgEngineer Před rokem +1

    I feel like half of the problems he listed are related to JAVA and not OOP in general. He probably had more than just a few bad encounters with a java code base.
    Also asserting that "TDD" is just a way to fix OOP's problems is just straight up bs.

  • @SimGunther
    @SimGunther Před rokem +1

    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...

  • @robfielding8566
    @robfielding8566 Před 8 měsíci

    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.

  • @Cesarhaha
    @Cesarhaha Před rokem +23

    I’d put you in the same category of Jonathan Blow as not really welcoming more people in with your strong absolutes. I’ll still watch you for some diamond in the rough takes but I have trouble recommending your videos.

    • @calebvear7381
      @calebvear7381 Před rokem +6

      I don’t really get what upsets him about Jonathan Blow anyway. His main criticism is that Jonathan complains a lot without providing solutions. Meanwhile Jonathan is literally creating a new language and game engine to try and show what he thinks would be better. This video we are watching even credits Jonathan with an idea for having an inline function that doesn’t share context so clearly Jonathan is sharing some ideas on ways things can be improved.
      I guess Jonathan is quite critical of web programmers and that strikes the nerve with Theo. Jonathan is not really offering solutions in the web space but does have a lot of valid criticism for example the amount of difficulty it can be sometimes to just get some kind of bundling problem resolved or when trying to upgrade one package wastes an entire day trying to work out why you can’t get the damn thing to build anymore.
      Jonathan also says you want a strongly typed language because in the long run it makes a lot of things much easier. That’s something Theo seems to agree with as he is often advocating for using type script everywhere (I agree with both on this point).
      The main criticism I have of Jonathan is that he often doesn’t seem to understand that not every problem is worth spending the time to do it in the most performant way possible. There are a lot of business level code where the speed is almost not relevant since the computer is so fast. In these cases it is more important that the rules and logic are correct than that we save every millisecond of processing time. When I’m writing that kind of code I don’t really want to have to think about memory management etc so I’m willing to pay the cost of having a garbage collector etc. So I don’t agree with Jonathan on everything but I do find his perspective interesting and I’ve had some good ideas flow out of watching some of his videos. I’ve seen several videos from Theo now where he makes disparaging remarks about Jonathan and I find it off putting. I’ve found some interesting projects mentioned on Theo’s videos so I’ll probably still watch him from time to time but it does make me like him less.

    • @fadious_padious2711
      @fadious_padious2711 Před rokem +2

      Yeah I have never seen one of this guys (Theo) video before. I have followed Jonathan Blow and Casey Muratori for a long time. Both have helped me tremendously and both have created solutions and shown solutions to the things they complain about. Yes they give web programmers a hard time and shit on the state of web programming because it's absolutely insane. The trace from a React component to the cpu is long and complicated, the sheer number of errors you will see if you open the console on any major site now is insane.

  • @paulsalele3844
    @paulsalele3844 Před rokem

    Great content Theo!!

  • @danielthompson2561
    @danielthompson2561 Před rokem

    Can anyone explain to me what “minimise state” means within the context of procedural/functional vs oop/imperative?
    I understand segregate state in the context of oop, I don’t understand how state can be “minimised”

  • @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

  • @Xania-js
    @Xania-js Před rokem

    the 'use' block is some what comparable with the static local function in C#

  • @scvnthorpe__
    @scvnthorpe__ Před rokem

    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__ Před rokem

      (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.)

  • @baka_baca
    @baka_baca Před rokem

    How is OOP like the children's book, "When You Give A Mouse A Cookie"?
    If you give a dev a "class", they will want inheritance. If you give them inheritance, they will want abstract classes and interfaces. If you give them these things they will want dependency injection (DP). If you give them DP, they will want to automate their DP... Oh and long chains of inheritance... And oh we better plan the entire hierarchy and project from start to finish... Maybe we can diagram it...
    (a month later management walks in)...
    "So devs, how's the project coming along?"
    "Great! We're almost done figuring out how to diagram the application, it's going to be perfect!"
    "Wait... Do we have anything to show other than this plan and diagram?"
    "Well no but, this is all super important and necessary so we can actually get started!"
    ...
    ...
    Oh how I wish this wasn't reality. Going through this at work now because I made the mistake of writing a "class" because that's what all documentation says to use for a tech stack and I wanted to leverage existing docs. I gave my team a class and 1 level of inheritance and have been battling back against an unreal amount of complex ideas that keep coming up to do very simple tasks. I guess I have a lot of teaching to do about rejecting nearly everything people do with OOP just so we can get some dang work done.

  • @leosin5767
    @leosin5767 Před rokem

    Laughed so hard when the win32 thing with Hungarian notation came out

  • @uipo1122
    @uipo1122 Před rokem +2

    5:05
    That is simply not true. Jon has said many times one simple thing: do the simpliest thing to solve the problem, don't complicate things, don't create needless abstraction. You can see him using this "methodology" on streams.

    • @zacharychristy8928
      @zacharychristy8928 Před rokem

      I disagree with Blow on a bunch of things, but they really did him dirty in this video.

  • @ConcerninglyWiseAlligator
    @ConcerninglyWiseAlligator Před 5 měsíci

    53:13 Yeah, despite what Unity would like you to believe, game dev and OOP don't mix well, like at all.
    Games really care about performance and OOP, along with how it incentivizes to disperse your memory all over the heap, is actively detrimental to code with good performance. Because hitting cache is a 1000x speedup.

  • @MrJoseklon
    @MrJoseklon Před rokem

    Glad to see Brian Will being recognized