Don't Model the Problem

Поділитися
Вставка
  • Опубліковано 28 вер 2024
  • Commenting on Casey Muratori's article "Clean Code, Horrible Performance". Turns out I can't add links to the description without performing "additional verification", but I'm sure you can find it on Google.

КОМЕНТАРІ • 138

  • @jumpingphantom
    @jumpingphantom 3 місяці тому +126

    "An idiot admires complexity, a genius admires simplicity"
    - Terry A. Davis

    • @mumk
      @mumk 2 місяці тому +7

      Holy C

    • @CaptainWumbo
      @CaptainWumbo 2 місяці тому +1

      hahaha I opened the comments to quote this. This good word needs to be spread wide and far, but I guess the trouble is some people view notation and brevity itself as complex. To which you have to quote Rich Hickey, simple not easy.
      The longer you can resist extracting behaviour the easier life is, I've found.

    • @nyrtzi
      @nyrtzi 2 місяці тому +1

      ​@@CaptainWumbo From what I've seen people don't really have a problem with notation and brevity itself but how big and complex the mental model one needs to run in their heads in order to translate the written code to an understanding of what the code does. But seeing that you're mentioning Rich I assume you're into functional and the reason why functional might be hard for many is that they've been conditioned to think of the meaning of their programs strictly through an imperative model... which reminds me of the Dijkstra joke "It is practically impossible to teach good programming style to students that have had prior exposure to BASIC; as potential programmers they are mentally mutilated beyond hope of regeneration."

    • @hollowbs7
      @hollowbs7 2 місяці тому +1

      This is actually really interesting.

  • @threeprongedfork7061
    @threeprongedfork7061 3 місяці тому +11

    I think a very important thing to remember is the requirements of the program. If you know they won't change, then don't worry about the ability to change your code. The solid principles are for being able to adapt to changing requirements, every talk at a conference i've seen about how to refactor your code following Fowler's patterns starts by saying 'if it aint broke don't fix it'

  • @Hector-bj3ls
    @Hector-bj3ls 3 місяці тому +11

    The other thing to remember is: you can't architect for performance after the fact.
    Why do we keep seeing big businesses rewriting their applications over and over? Microsoft recently rewrote Teams for performance and it's still super slow.

    • @Hector-bj3ls
      @Hector-bj3ls 3 місяці тому +3

      @@wbay3848 That's more to my point. They're built on the same underlying technologies. And yet Discord works fairly well, while Teams is a dumpster fire. Similarly, Slack works fine majority of the time also.

  • @Nikoline_The_Great
    @Nikoline_The_Great 3 місяці тому +42

    Yeah. I am super happy that I was already over my OOP phase when I did my bachelor. I could have been sucked down that path easily.
    I had just done some C when I realized how I don't really like OOP. I was really enjoying how much of my mental energy went towards solving the problem instead of modelling it.

    • @NabekenProG87
      @NabekenProG87 3 місяці тому +6

      I remember learning Java in school and trying to write Minecraft mods. Modelling everything as classes broke my brain.
      Every problem screams of having to apply some clean code pattern. Not really beginner friendly.
      Using Python with flat inheritance and mainly functions was way easier for me to get into programming.

  • @dr4t
    @dr4t 3 місяці тому +8

    Thank you for addressing the issue of having thousands (not an exaggeration) of queries for a single page load because of all the silly abstractions, and especially because of the use of ORMs, which somehow ended up as being an industry standard in modern web development. And all those thousands of queries could be transformed into 1 to 5 separated queries. It's mind numbingly dumb.

  • @simonrigby2776
    @simonrigby2776 3 місяці тому +6

    I may have missed Casey making this exact point, but it's a good one and points to the bigger issue of where your head is at when you even start thinking about the problem. I'm always slightly nervous when the first points of contention on a project are architectural when meanwhile the problem is not solved.

  • @borkware
    @borkware 3 місяці тому +20

    Does `curr` need to get assigned at the bottom of the loop? Otherwise, looks like it's generating the path from (0, 0) each time rather than touring the points. (And if that's an actual bug, it was much easier to find in the shorter code :-) )

    • @davidhart1578
      @davidhart1578  3 місяці тому +15

      You are correct 😂 spotted it after uploading and immediately facepalmed

    • @TroelsDamgaard
      @TroelsDamgaard 3 місяці тому +1

      Yup, was just looking through, if somebody spotted this, as well. 👍

  • @oscarfriberg7661
    @oscarfriberg7661 3 місяці тому +12

    A mistake many make with these principles is that they never divert from them. There are cases where these principles are useful, but that doesn't mean they should be applied all the time! Only apply these principles if it helps you achieve your goal. If you don't have any good motivation for your extra code other than "it might be nice to have", then you ain't gonna need it!
    Your simple example is a perfect starting point for any code. It's short, isolated and testable. It's everything that's needed to ensure maintainability. It doesn't assume anything about how the code will grow in the future.
    If you want to extend this code with more features, then maybe it's reasonable to apply some of the principles to make it easier to maintain. But only if it makes sense! If you don't need this AbstractFactory now, then you shouldn't implement it. Implement it when it's actually needed. The risk of doing it too early is that you might abstract your code with the completely wrong assumptions. Now you have extra obfuscated code built on the wrong assumptions!

  • @JoeyJooste
    @JoeyJooste 3 місяці тому +4

    This gives me a lot to think about, I really like how simply you broke it down. I'm going to consider this when writing code in the future.

  • @PROdotes
    @PROdotes 3 місяці тому +5

    It's all a case by case basis, isn't it... i wrote an app for work that emails my boss if the software process can't be found, and it checks for it every 5 minutes...
    for that i don't really need clean code, i just need a few lines to do a job...
    but when you're doing a complex system that maybe multiple people are working on with you, you want people to go "well that functionality is prolly in here somewhere" and not look through 1000s of lines of code...

    • @poguri27
      @poguri27 2 місяці тому +2

      Nuance and context are completely lost on people making "everyone (but me) is doing programming wrong" style videos like this and Casey muratori.

  • @AlfredSYoung
    @AlfredSYoung 3 місяці тому +8

    This is a compelling example but consider that in many cases the user is describing the requirements of the software to a semi-technical intermediary who then needs to convey them to the programmers. Furthermore, if the software is successful, then other programmers need to be brought on who will likely start with zero understanding of the business that the software should support. Modelling the problem can helps alleviate miscommunications that can occur during this game of telephone and serves as documentation of the business. So while the code might be short and fast without a model I wonder whether it will do the thing the user requires after a few iterations of adding features to it.

    • @oliver_twistor
      @oliver_twistor 2 місяці тому +4

      Great point! I think very short model-less code would need a lot of documentation to make up for the lack of models. Then, one has to ask themselves, have they won anything if they would need to spend a lot of time writing documentation instead.

    • @abdrnasr
      @abdrnasr 2 місяці тому +3

      Most online educators of programming say YOU HAVE TO USE SOLID. Most beginners when they hear this, they will just do so.
      What i believe is that the level modularity should depend on what the problem being solved is. Just as he mentioned in the video games may require more performance so you should probably leave refactoring only when actually needed.

    • @poguri27
      @poguri27 2 місяці тому +1

      And furthermore, modeling the business domain accurately means it's much easier to evolve the code as the business requirements evolve. It's one of the key points of domain driven design.

    • @anon3118
      @anon3118 2 місяці тому +1

      That should be made into comments imo. Kinda the point of it

    • @AlfredSYoung
      @AlfredSYoung 2 місяці тому +1

      @@anon3118 but you can't test comments and programmers aren't exactly know for their communication skills

  • @timmy7201
    @timmy7201 2 місяці тому +1

    As an embedded engineer, who often needs to squeeze as much performance out of under-powered hardware...
    The more "factories" and abstraction I see in someones code, the more I deem set developer unworthy of his title!
    I've had many discussions with various developers over the years. Many claim that abstraction is best practice, as it prepares the code for future changes without having to rewrite everything. So instead of writing simpler understandable code in 1 day, they spend 5 days on the problem making it overly abstract and unreadable, but more "modular" against future changes.
    By the time actual changes need to be made to set code base, nobody understands how it works... Thus another 5 days are spend untangling the whole mess, to make simple changes that shouldn't take more than 2 hours... After these changes things appear to work, most of the time... But nobody understands why it sometimes bugs out...
    Writing the code simple and understandable would meanwhile take 1 day, rewriting it upon changes a second day... That's 8 days less wasted time, with most likely less bugs!

  • @vasiliigulevich9202
    @vasiliigulevich9202 2 місяці тому +2

    Obviously clarification about optimality is a trick condition!
    If the path is not important return full field traversal constant that would clean the whole field independently of where the dirt is. There it no code more elegant than no code!

  • @yt-sh
    @yt-sh Місяць тому

    there is this video called I love deleting code and I have never felt more productive while building apps

  • @fennecbesixdouze1794
    @fennecbesixdouze1794 3 місяці тому +10

    You've really missed the point.
    The reason you model the problem (in this very particular OO way*) is because you want to communicate in the same language as the domain you are working in, because typically you are solving real problems for real people who want to solve many problems in the same related area.
    If I make a robot for someone that can go between points that need cleaning and, I show it to them cleaning an empty room with no obstacles, then they come back and say:
    "Hey, I bought a chair, can you update my robot so it can still vacuum my room?"
    You want to be in a position to say "yes" instead of "oh no, this algorithm can't handle any obstacles in the room, this will require a complete rewrite" and then have to explain tot he client why this thing that seems like it "should be easy" to them isn't easy, because it violates some mathematical constraint that was key to the solution you delivered to the previous problem that, to the client, seems very similar.
    When you model the problem and model the robot vacuum and the points as agents with internal logic, you immediately have a direction to go to solve the next problem with the additional obstacle: e.g. you could update the method the robot uses to determine its next step to account for obstacles in the room.
    If you devised some algorithmic solution using very specific mathematical constraints, like "we can always just move to the same coordinate N/S and then to the same coordinate E/W", there is no reason to believe any kind of similar approach could possibly be reusable to solve similar problems.
    In mathematics, the map from problem statement to "can it be solved mathematically" is highly non-continuous: when very specific constraints align, we can come up with a nice clean mathematical solution. When they change slightly (in the way problems in the real world do), you can often end up with a case where there is no mathematical solution.
    Providing clean mathematical solutions to programming problems is an extremely valuable skill, of course. Especially if those programming problems are generic enough that the clean mathematical solution is very useful for solving sub-cases of other programming problems. If you are so blinded by the OOP approach that you can't even come up with the clean mathematical solution to this vacuum problem, then you are missing some crucial skills as a developer, namely mathematical skills.
    But if you just think "oh this solution has less code so better, the only reason to model problems is gate-keeping" you really don't get it.
    Sometimes you need to model, other times e.g. when the problem is extremely well-defined and you can treat the constraints with mathematical precision, then you can optimize using those constraints. Casey will tell you the exact same thing.
    Neither one of those solutions you presented is "better" than the other. Neither have I "conditioned" myself to think is better than the other. They are solving completely different problems: one is modeling the problem using agents and actors, the other is modeling it as a pure maths problem. One type of modeling is more appropriate for some benefits: one provides flexibility, simulation, being able to explore variations in behaviors, possibility to tweak the agents and actors and then experiment with the results to solve similar problems. The other provides mathematical precision, the ability to arrive at an optimal solution, etc. Neither is "more readable", neither is "more clean", and neither has anything whatever to do with "clean code" or "Clean Code".
    *footnote: you are actually modeling the problem in both cases, btw. What you're really noticing the difference between are highly abstract mathematical models like you gave in your second solution, versus very concrete OOP-style actor-based models that you used in your first. In OOP you're encouraged to think about things in terms of agents and actors and model in that very particular way.

    • @mrcoldshower465
      @mrcoldshower465 2 місяці тому +2

      100% agree. Clean code complements the open/closed principle where the modules are easily extendable. Making it easier for the whole team to keep adding features. So, you just get more done with clean code, because it simply makes everything so easy to extend.

  • @speedychicken831
    @speedychicken831 2 місяці тому +1

    David Hart + Internet of Bugs are the best programming channels on YT!

  • @mvargasmoran
    @mvargasmoran 2 місяці тому

    My Man doing the PHPs

  • @arcane3327
    @arcane3327 3 місяці тому

    Dude i don't know much ruby but i think your solution is concise and therefore more readable. I don't really know the underlying machine instructions of ruby but i can image since you are just concatenating the string with 2 small structs this has less overhead. Also i think it's nice you used locality of behaviour, so it's just a plain function that does all you need in one place. Thumbs up :)

  • @yuqii65535
    @yuqii65535 3 місяці тому

    Given that it's not relevant how optimal the path is we can reset back to (0,0) after each clean and then every point can be encoded trivially:
    const P = (v, d) => "".padEnd(v, d)
    return points.map(({ x, y }) => P(x,"E") + P(y,"N") + "C" + P(x,"W") + P(y,"S")).join("")
    This can be expanded later if ever desired:
    - sort the points first
    - collapse the resulting string to improve efficiency (NCSSSNNNN > NCN etc)
    Complex solutions turn out a huge pain when the requirements change (and they will change).

  • @Candyapplebone
    @Candyapplebone 2 місяці тому +1

    “This is Ruby, which I won’t comment on” 😂
    I’m currently aligning my team to focus on cleaning up code. However, it is not for the sake of just having clean code, although I do want that a lot. No, I found an actual business use for this. We want to factor massive amounts of code so that we can upgrade a system to a modern one. We cannot do it if there are a lot of tests in place. Currently the code has almost no tests and is not organized. So while I agree with your message, at least I know that in my own personal experience currently, I’m not just cleaning up code for the sake of it.
    Edit 2: I’ll make a note not to fall into the trap you layed out here

  • @joshuatye1027
    @joshuatye1027 3 місяці тому

    I have a similar experience with my first app. It's so dead simple I've never had to touch it. It's still in use.

  • @elmigranto
    @elmigranto 3 місяці тому

    Since the path being optimal is not important, simply printing hardcoded string that visits all cells should be best, most performant solution :)

  • @ShehabEllithy
    @ShehabEllithy 2 місяці тому

    "Which I won't comment on" is hilarious

  • @aslkdjfzxcv9779
    @aslkdjfzxcv9779 3 місяці тому

    when will we ever acheive the silver-bullet paradigm?
    i know, lemme ask "ai ."
    xD

  • @shiningstar7481
    @shiningstar7481 2 місяці тому

    At least my code should be easy to extend when I return a month later. 😂 Someone asked for some of my code so they could use it and speed up their own project. Never heard from them again.

  • @PhysicsITGuy
    @PhysicsITGuy 2 місяці тому +2

    This is great. I totally agree. I'd rather have one big function than twenty one-liners across three files.
    Clean code ignores "interface complexity."
    If your code only has one or two functions, then you know what to call and how it works. It is easier to use that code, because there are only one or two interfaces that you need to understand.
    The most difficult libraries to use have tons of little helper functions that all do slightly different versions of the same thing.

  • @KimHogeling
    @KimHogeling 2 місяці тому +1

    Please consider increasing the font size a little next time :)

    • @davidhart1578
      @davidhart1578  2 місяці тому

      Good shout, will do 👍

    • @KimHogeling
      @KimHogeling 2 місяці тому

      ​@@davidhart1578 Nevertheless this is a great video with fitting example. Thanks for making it! 👍

  • @nyrtzi
    @nyrtzi 2 місяці тому

    I guess the folks applying Clean Code forgot that every piece of it is a trade-off and that one shouldn't add that structure neither to the code nor to the processes around the code by default but only when it pays for itself... and lots of code isn't big or complicated enough to justify bringing in all of that heavy machinery. If you don't have multiple database backends yet then what's the point of abstracting away behind a generic interface the only one you have? Isn't one classic story of Agile the one where they make a wiki but first use a in-memory database while that's plenty for the software to do its job, then switch to files on disk when persistence becomes a requirement and then never end up implementation database storage because there was no real need for it... while in the meanwhile many projects start by first adding the database storage backend simply because it's tradition. I'm not saying this to promote agile but just to say that indeed why add something when there's no practical reason to.

  • @davidshipman5964
    @davidshipman5964 3 місяці тому

    Awesome video

  • @sardaukar99
    @sardaukar99 Місяць тому

    This is is not a technical problem - this is a business problem (ease of onboarding, developer fungibility, preference for cheaper devs, average dev tenure being 18 months, etc.) bleeding onto the technical realm. Don't blame devs for wanting to keep their paychecks.
    There's no single "right" answer to a coding task in a professional setting - there are multiple variables like how rushed we are for it, are we ok with introducing debt, etc. To comment and analyze them in isolation of these concerns is to muddy the waters and introduce false universals which, as a senior dev, are the most tiresome things to discuss and go back to in online discourse about coding.
    Also, the "this is Ruby... which I won't comment on" with a smirk at 3:26 has been done to death. Give people's preferred tools their space and stop being derisive on the side, it's not helpful and doesn't move the industry forward at all. Do _you_ want your comments filled with "PHP yuck" comments? Would that help?

    • @davidhart1578
      @davidhart1578  Місяць тому +1

      Fair point, I guess it goes unstated that this is my opinion. I agree that axioms are bad, and it's why I made the video, but maybe in stating the opposite opinion I'm doing the same thing. I find PHP and JS developers have the decency to admit their language is garbage however :p Ruby less so

    • @sardaukar99
      @sardaukar99 Місяць тому +1

      @@davidhart1578 there's plenty of garbage in any lang :D I love Ruby, but it's like what Ward Cunningham said of Smalltalk and why it failed: "it was too easy to make a mess". It takes discipline to prevent that, and we all know how disciplined devs are in general.
      Thanks for the reply, I really feel that if we start from empathy the online programming discourse can move forward 👍

  • @m13v2
    @m13v2 3 місяці тому +4

    oop/clean code originate from smalltalk, where the idea was to provide code which users could adjust to their own needs.
    performance is something for the jit compiler to handle in this scenario.

    • @marcsfeh
      @marcsfeh 3 місяці тому +2

      OOP and clean code/SOLID are completely distinct things.

  • @KushLemon
    @KushLemon 3 місяці тому +2

    Another one who completely drinks the koolaid. Write like Casey in enterprise codebases, get fired for creating an unmaintainable mess.

    • @sudsy3
      @sudsy3 2 місяці тому

      Casey’s code is more maintainable you fool

  • @martinevans8984
    @martinevans8984 3 місяці тому +190

    It’s kinda crazy how in our attempts to escape unstructured spaghetti code we have just invented structured spaghetti code instead

    • @kevinscales
      @kevinscales 3 місяці тому +23

      It's brilliant, just formalize the spaghetti. Now you just have to memorize these twelve ambiguous rules about how to construct your spaghetti to be accepted into the cult.

    • @arcane3327
      @arcane3327 3 місяці тому +3

      /r/angryupvote
      here. take this.

    • @jorg1piano
      @jorg1piano 2 місяці тому

      100%

    • @nyrtzi
      @nyrtzi 2 місяці тому +2

      We took it too far and that led to problems which then gave birth to a whole industry that then lives on making it all worse in order to sell more things.

    • @l3lackoutsMedia
      @l3lackoutsMedia 2 місяці тому +2

      Gatekeeping and standardization for the spaghetti

  • @saniancreations
    @saniancreations 3 місяці тому +58

    " _Clean_ code is what you optimize for when _good_ code is not a requirement", now that's a quote right there! I'll be taking that one thankyouverymuch

  • @zeidrichthorene
    @zeidrichthorene 3 місяці тому +23

    The code at 7:30 is simple enough it's also easy to point out the bug. As you iterate through the list of points, curr.x and curr.y aren't updated. This means the robot is always planning the path from the original starting position. you need to set curr to point at the end, then the new starting position will be the position of the previous point.

  • @piff57paff
    @piff57paff 2 місяці тому +11

    One thing I always notice when people try to make OOP, design patterns or clean code look bad is, that they only use trivial toy examples that fit in a single screen.
    If your problem is small in size and short lived in development life cycle just go quick and dirty. But if you need to maintain, extend and evolve a 1 million line system for 20 years with 10 developers, you will need to follow some principles to a achieve structure.
    Patterns are a standardized solution for a recurring problem (and also come with pros, cons, situations when (not) to use explicitly called out). I'd rather have 20 times a builder pattern or decorator in the code base than 20 times developers reinvent the wheel. Patterns also give a standardized way to communicate concepts very efficiently. Just try to verbalize that you solved the problem with an Adaptor Factory without these two words and see how many you'll need. ^^
    I surely don't agree with every single sentence in "Clean Code", but structure can make complexity manageable. Do these concepts create overhead and reduce performance? Sure. But at a certain complexity a somewhat slower program is still better than a fast program that needs to be thrown away because it can't be adapted to new requirements.
    All of coding and engineering has one rule: There is not a single perfect solution for every problem. Everything is a tradeoff. But knowing as many options as possible (with their pros and cons) allows you to make that tradeoff consciously and increases your chance for success.

  • @drxyd
    @drxyd 3 місяці тому +7

    There's something very satisfying about finding a succinct and natural way of expressing code, I never got too far into the whole clean code thing mainly because it made this thing I liked to do into a chore and I actually like refactoring.

  • @karamzing
    @karamzing 3 місяці тому +6

    I think that the first approach can feel more satisfying as a test answer because modelling the problem sort of gives more context to the reader, whereas the second example can feel overly terse. OTOH when the exact same code is part of a larger code base, one appreciates the shorter solution more because there is all that other code to deal with.

  • @myyoutubepage1
    @myyoutubepage1 2 місяці тому +3

    You seem like a kindred spirit. I hope you keep making videos, as long as you feel like it.

  • @consolebuche6051
    @consolebuche6051 3 місяці тому +5

    YES. YES. AND YES.

  • @ruivfsalgado
    @ruivfsalgado 3 місяці тому +5

    Preach it brother!

  • @ChrisAthanas
    @ChrisAthanas 2 місяці тому +4

    Ah yes "Book Driven Development" of Clean code
    I talk about this in my free course how to program from the ground up on my channel

    • @RoboDragonJediKnight
      @RoboDragonJediKnight 2 місяці тому

      Great course. A real diamond in the rough. If more modern CS and software engineering education were less polluted with dogmatic OO design, I think we would have more engaged grads and software engineers.

    • @ChrisAthanas
      @ChrisAthanas 2 місяці тому +1

      @@RoboDragonJediKnight thank you! yeah the OOP was a major head fake by AT&T at the time
      It has its place but I would not reach for it immediately at this point

    • @RoboDragonJediKnight
      @RoboDragonJediKnight 2 місяці тому +1

      @@ChrisAthanas I once heard some software design/architect consultant say that "a method should be no more than about two lines" full stop.
      When it comes to software design, I have really resonated moreso with the ideas provided by educators like John Ousterhout. There's a certain quality to it that I think is a good antidote to "Clean code" movement. Mainly I resonated with some of his ideas on depth versus breadth and using real world examples "open" syscall in Unix-based systems rather than some contrived OO taxonomy soup. Watching your book driven development talk now.

    • @RoboDragonJediKnight
      @RoboDragonJediKnight 2 місяці тому

      @@ChrisAthanas I think I heard a software consultant say something to the effect of "a method should be no more than two lines".
      I have found myself much more resonant with ideas of John Ousterhout on software design. Mainly have engaged with his Software Design google talk and it has made me more interested in the space. I recall him giving much more concrete non-trivial examples such as say Unix I/O syscalls like read(2) to illustrate the idea of "breadth versus depth" in API design. Compare this to OO education which gives the most contrived examples of Animal taxonomy and foos and bars. Watching your book-driven development video now.

  • @JonMW
    @JonMW 2 місяці тому +1

    Preaching to the choir. I'm a big fan of Jack Diederich's talk, "Stop Writing Classes". There's no point building a huge edifice of extra flow control and abstraction to lay groundwork for features you THINK you'll need in the future. Nobody's got enough information to know for sure what those future needs will be. Just wait until you do know, and expand (or rewrite it) then. Maximise Work Not Done.
    Addendum: I've put in a few software projects at work that we use internally. The one I hate the least, by far, and needs the least maintenance, is (non-coincidentally) the one that's maximally simple.

  • @Hector-bj3ls
    @Hector-bj3ls 3 місяці тому +2

    Just on your point about performance at the beginning of the video.
    You mentioned that people will wait for a website that provides interesting content or useful services. They will switch if there is a faster version though.
    Take reddit. People used alternate clients all the time because they were faster.
    Or, in the case of services, sometimes people are willing to sacrifice certain features if it means working without waiting.
    So performance is a selling point.

  • @koool56
    @koool56 3 місяці тому +4

    Great video

  • @cosorxndrw
    @cosorxndrw 3 місяці тому +3

    Have my like, good sir!

  • @el_carbonara
    @el_carbonara 2 місяці тому +10

    points taken, but your example simply shows an elegant solution that satisfies the minimum requirements, It looks like an equally valid solution that would be testing the same way asserting the final state which is how I would imagine many algorithmic code is tested anyway...
    throw in state management, side effects and more complexity you will soon start to regret your decision of trying to "keep it simple". ill be the first to admit I gatekeep structuring code in a way that makes it easy to test only because I get sick of seeing lots of devs writing sloppy untestable code because they don't even consider testing in the first place then a bunch of bugs happen because of this laziness or skill issue which then causes heated arguments and copious amounts of BS to bicker about coding philosophies.
    sure, you can take it to the extreme some frameworks do but applying some basic principles will do a world of good. What you showed basically just reminds me to take a step back, think about the problem more and then apply some common sense to get a happy medium between the 2.
    Basically what happens is an inexperienced dev will come in to your elegant solution and try expand it as new requirements come in and chucks everything in the 1 method that includes any side effects and it just ends up as a bloody shit show hot mess. Without experience to review these changes you end up with a shit show of a code base.

    • @cernunnos123
      @cernunnos123 2 місяці тому

      > try expand it as new requirements come in and chucks everything in the 1 method that includes any side effects
      thisss, just by reading it ptsd kicks in.
      > Without experience to review these changes
      check for new tests, no new tests? request changes

    • @oscarfriberg7661
      @oscarfriberg7661 2 місяці тому

      @@el_carbonara If an inexperienced dev makes a hot mess of the simple solution then that’s a problem in your code reviewing process.
      IMO, it’s often better to start with a simple solution, and then make it more structured as requirements expands. The risk of going all in on making it structured the first round is that you’re likely optimizing for the wrong requirements. It’s difficult to expect beforehand how code will grow over time.

    • @el_carbonara
      @el_carbonara 2 місяці тому

      @@oscarfriberg7661 it isn't my problem (it is an industry problem). How many times have I heard that. The shit code will go in from day one and it will gradually get shitter.

  • @markuskluever4059
    @markuskluever4059 3 місяці тому +18

    I was in a software engineering course last year when I was 19. I quickly learned that It's very hard to find good advise about programming style. Here's my thought-experiment: If you pick a random view/stance for example "oop is good", then you could easily find many many people with decades of experience who all share that view, no matter what the view is. I thus started to base my opinion on what I like. As someone who was forced to use c# with all the inheritance shit, and as someone who likes to write my own games and stuff in c, I prefer c and it's style. Jonathan Blow once said that a program is made up of nodes that talk to each other, wether they are functions, or classes or whatever. He said that if the number of 'nodes' in the program is N, then the complexity of the program > n2, which totally resonated with me.

    • @ckjdinnj
      @ckjdinnj 3 місяці тому +6

      It’s an interesting thought. Certainly not accurate, but it does convey an important element of evaluating complexity in logical way as opposed to a feeling.

    • @paligamy93
      @paligamy93 3 місяці тому +3

      There's only 2 real programming rules to follow:
      1. If its fast enough stop optimizing. Because you're very expensive to the company. And you have to profile to even know if it is fast enough and you have to have the product pretty far along to know if it isn't fast enough.
      2. If its not fast enough, try to break as few conventions as possible to get it fast enough. In a real world application there's not an infinite number of things your application is going to be expected to do and many of these features are going to be some slight variation on other features and there's going to be more than 2 or 3 of the variations there's going to be 35 and a refactoring is again going to be super expensive in man-hours to get through. This is also why people say programming in a way to expect change is a good thing.
      3. You will make mistakes and they will be difficult to find and the only real solutions to them will break what you consider to be a straight forward way of addressing that problem so you will need to use tools that other people have made in an attempt to find these problems before they find you and/or guarantee you got it right. This is not a rule this is a fact of life.
      Rule 2 is why the greybeards think "OOP is good" because there's a lot of smaller rules in that statement that end up supporting "OOP is good". But besides those two the rest of the rules are just pirate rules. You absolutely should break them if you have a moderately good reason for it. As long as you document why you had to break them and that's only if you're working with other people and many times document doesn't mean leave a comment it means leave a comment in the PR or some other tracking tool

    • @McSlobo
      @McSlobo 2 місяці тому

      They're just tools. OOP is a toolset, functional is just a toolset. When you're experienced and do real work for real money, you'll know which too you'll need to apply to get the job done in a reasonable time frame. It's rare you have to find otherwise optimal solution except short term cost (i.e. minimize your time used on the problem).

    • @piff57paff
      @piff57paff 2 місяці тому +3

      Saying "OOP is the best solution" or "FP is the best solution" is like saying "A hammer is the best tool". ;) It's all about context. Would I program a microcontroller in Java? Nope. Would I program a web service in Assembler? Also nope.

    • @oscarfriberg7661
      @oscarfriberg7661 2 місяці тому

      @@markuskluever4059 There’s a big difference between programs made by a solo dev with full control over the scope of the project, and programs made by large teams and with stakeholders who don’t know what they really want. OOP is made to accommodate problems that come with the latter.
      Jonathan Blow is speaking more from the small game dev team point of view. I don’t really know how large his team is, but it’s evident from his perspectives he’s not facing the challenges of working in large teams. Obviously OOP doesn’t apply to small game dev teams, because OOP isn’t made for these kinds of problems.

  • @hawkbirdtree3660
    @hawkbirdtree3660 3 місяці тому +2

    “Clean Code” is not about software performance, or about increasing programming efficiency; it’s about selling you books. “CC” is a digital Rube Goldberg machine

  • @megetmorsomt
    @megetmorsomt 3 місяці тому +2

    KISS

  • @huveja9799
    @huveja9799 3 місяці тому +1

    I have a theory, just as "Clean code" is also a theory. Just because something seems to make common sense, or make sense, doesn't mean it actually makes sense.
    A paradigmatic example is the ancient belief of the Earth the center of the universe, and the Sun rotating around the Earth, that theory had a lot of common sense, but nothing could be further from reality.
    If someone tells me that a set of practices and patterns have certain benefits, such as the maintainability of a system, that's a theory, i.e. a hypothesis, and by now we should all know the following, the one that proposes an hypothesis must try to falsify this hypothesis by testing its predictability power against empirical observations. When that doesn't happen, well, the theory is a good business for the one who proposes it, and a very bad business for the rest who has to "consume" it.
    "Clean code" is a nice theory, but no more than that, therefore I would be careful with what I evaluate, people are going to tend to optimize that to the detriment of what is not evaluated ..

  • @jorg1piano
    @jorg1piano 2 місяці тому +1

    Very good video! I dont think the long version is more unit testable even.

  • @argbatargbat8645
    @argbatargbat8645 2 місяці тому +1

    Same as all engendering stuff… use the tool that better fit the solution. Apply clean code as described by uncle bob in a game or in the algorithm shown here is not the choice to go.

  • @AdamWall-u8r
    @AdamWall-u8r 2 місяці тому +1

    Just spotted the bug. In your loop, you're missing the `curr = point` that should be at the end of each iteration.

  • @macchiato_1881
    @macchiato_1881 2 місяці тому

    I think cleanliness is considered an important metric in large production codebases because companies are constantly asking for new features, and that may result in constant refactoring, having to integrate old features with new ones, coupling and uncoupling features, etc.
    While it is sad that performance is not an important metric as it used to be, I guess that's the price you pay for the constant need to accomodate the users' demands.

  • @eyesopen6110
    @eyesopen6110 2 місяці тому

    "clean" code, "agile" - tools of the inexperienced.

  • @yf4453
    @yf4453 2 місяці тому

    Is the struct even needed? An tuple or array for the x,y of the point

  • @mateuszmazurczak1268
    @mateuszmazurczak1268 2 місяці тому +1

    Just because something was tough to do or complex, doesn't mean it is valuable.
    I couldn't agree more with what you are saying. Adding abstractions, factories etc. may make sense, but when problem requires it. And not every problem requires it. It is important to know the patterns, to know the tools. But the hardest part about being SD is to decide when to use them or not. And there is no golden bullet that fits all.

    • @oliver_twistor
      @oliver_twistor 2 місяці тому

      Indeed. The worst example of overdoing things I've seen is a Java codebase I worked on that required us to have an interface for each concrete class, regardless of there ever be a rationale for having those interfaces implemented by more than one class each. As I saw it, all that codebase did was doubling the file count on the web server. Don't get me wrong, I'm all for interfaces and the benefits they bring, with testability, flexibility, structure etc., but sometimes it becomes too much.

  • @Taddy_Mason
    @Taddy_Mason 2 місяці тому

    9:41 is when i hit subscribe

  • @artimdutton
    @artimdutton 13 днів тому

    so all my life as a kid i programmed oop, its only as an adult that I value code that is fast, etc, etc. How do I get out of the oop mindset? Everywhere I turn I see oop and haven't been able to find good resources for this style of programming.

    • @davidhart1578
      @davidhart1578  13 днів тому

      That's a good question and I'm not sure if I have a great answer for you. I started the same way. I built a small Zelda style game in college and had this big plan to use the "inventory" pattern for the actual inventory. It ended up getting out of hand after a while and I realized my assumptions were wrong, so I couldn't refactor it without basically rewriting the whole thing.
      I think the best advice I've heard is to solve the problem you're dealing with right now. Around the time I made this video, I built a feature that we were going to expand on the sprint after. I knew they were going to add filtering etc so I built it with that in mind, but customer feedback indicated filtering wasn't important so the requirements completely changed. I was moved to another project and the team had to work with my weird abstraction that was created for a different problem.
      It's easier for the next person to build on something simple that just does one job, if that makes sense.

  • @zerotoanime3953
    @zerotoanime3953 2 місяці тому

    100% agree with this.

  • @poguri27
    @poguri27 2 місяці тому

    I find that people who make this point and trash OOP and related practices are simply inexperienced with the practice of domain driven design and why it is used in many places. Once you understand it better and see it used effectively, it gives you a bit more nuanced perspective on OOP. Dont knock it until you learn more about it, what problems it tries to solve and how it does so.
    Its frustrating watching noisy programmers on the Internet like blow, mutatori, and videos like this, preaching these things without really having a nuanced understanding of the massive swaths of technology and related practices they are writing off. Its grifting. It's designed to make fledgling developers think theyve stumbled on the one true way to code and the one true god of coding, simply by being loud and overconfident and mildy successful in one specific domain. It does not qualify them to make such widespread assertions about all software development. People who fall for these cult of personality celebrity developers inevitably take on this overconfident persona for themselves and become the most annoying people to work with.

    • @davidhart1578
      @davidhart1578  2 місяці тому

      At the end of the day it's about differing experiences and preferences. I've spent 10 years being told that code must be written in accordance with books from the 70s and 80s so I get frustrated by that. The people writing those books were frustrated with the problems they saw. We address the problems we see in our own experience, but the caveats always exist even if they go unstated. Personally I prefer this style of communication, when someone surrounds their position with "this is just my opinion but..." I often wonder if they think that's not implicit. Ultimately it's about the conversation, not any individual take. Thanks for sharing

  • @jackykoning
    @jackykoning 3 місяці тому +1

    boiler

  • @warrenhenning8064
    @warrenhenning8064 4 місяці тому +6

    7:28 is some of the nicest Ruby code I've ever seen.

  • @doc8527
    @doc8527 2 місяці тому

    My personal simple rule for "modeling" is that the model I create is to specifically benefit the current problem I'm going to solve, with a minimal level of flexibility by allowing copy/pasting, rather than trying to solve the future problem or extendibility.
    This sounds extremely counter intuitive, completely against any of my ideas before good amount of experience.
    But the life lesson of I saw a lot of devs running into is that they try so hard to predict the future and make their model to be future compatible, which turn out to introduce a lot of complexities/abstraction into the current architecture unnecessarily, has no benefits to the current model, and attempt to solve a lot of imaginary problems. At the end, no matter how senior/genius the person was, the real requirement always defeat their "perfect" models. And the original raw version without any models always tends to be more flexible.

  • @salvatoreshiggerino6810
    @salvatoreshiggerino6810 2 місяці тому

    Another point is that the tiny solution doesn't hurt nearly as much to throw away and redo when requirements change. Devs and maybe even more so their managers are obsessed with future proofing, but the only thing they accomplish is increasing the amount of rework when the future shows up and inevitably isn't what they thought it would be.

  • @liquidvapour
    @liquidvapour 2 місяці тому

    The latter example could be a little more self documenting. Maybe making the insight that all it uses is the Cartesian distance to the next point to clean.
    It takes a bit more to understand given the number of lines as it is more dense.

  • @tomsterbg8130
    @tomsterbg8130 2 місяці тому

    Every time that I write game code and scrap it to rewrite it better, it either doesn't work, or gets shorter. Some solutions are so simple, so elegant, yet they are much better than what I started with.

  • @SeánMee-b7l
    @SeánMee-b7l 2 місяці тому

    Your example was excellent in explaining the issue.

  • @SonAyoD
    @SonAyoD 3 місяці тому

    Very interesting

  • @josephp.3341
    @josephp.3341 2 місяці тому +4

    Make code that models what you actually want to happen, not some abstraction that loosely defines what you want to happen in a way that is intentionally vague.

    • @vasiliigulevich9202
      @vasiliigulevich9202 2 місяці тому

      This is fatal flaw, the purest solution for the problem as stated is to return a constant that cleans the whole field. No modeling is needed.
      This is a trick problem.

  • @mast_g
    @mast_g 3 місяці тому

    Back to cave.

  • @elijahbuscho7715
    @elijahbuscho7715 3 місяці тому +3

    I think this is example is very trivial and the benefits of clean code are poorly demonstrated.
    The problem with the short solution is that every single line needs to be read in order to understand it. The semantics of the problem have been abstracted out. The "clean" solution has clear, reusable semantically names functions. It may take a bit longer to get the full granular picture of what is happening, but once that's done, the code is much more easy to work with and reason about. It's also much more possible to understand the code without reading every single line. As long as you have some documentation and a description of how it behaves, the code is very easy to use and doesn't require the full granular picture. That is the non-trivial benefit of clean code.
    That being said, when performance is a concern, this "clean" code is bad, and must be rewritten in order to optimize it.
    But imo, I'd rather be able understand the semantics of the code without needed to read each line, so I prefer the "clean" implementation as a default.

  • @liquidvapour
    @liquidvapour 2 місяці тому +1

    The amount of code is directly related to the amount of bugs. Less code less bugs

  • @clementdato6328
    @clementdato6328 3 місяці тому

    I think that’s probably because your example does not involve state or any side effect. Points might be in a concurrent access, so you might want to gain the mutex before hand. And the same piece of computation could be reused but only in a dynamic way, so you may have cache, so on and so on. And then you want change your cache implementation, but according to a specific nuance for concrete cases. Also you might access a credential that your company only allow in their secured environment, so you may need some global access pattern to a global variable or you are passing a context all the way down.

  • @MarcosVMSoares
    @MarcosVMSoares 3 місяці тому

    For me, the second one exemplifies clean code. Clean code is clear and concise, prioritizing readability and maintainability over sheer performance. Performance is important, but making the code easier to read and maintain is the primary focus. Maybe it's because I prefer functional programming over object-oriented programming, but I think this Ruby code would be excellent in Elixir!

  • @mohamadybr
    @mohamadybr 3 місяці тому

    I personally like to mix both worlds. I like performant code but also enjoy writing code that I can read easily. as long as names are clear enough to me, I don't really care about the structure of the code. but at the end of the day, most companies will use these metrics to rate their candidates.

  • @7th_CAV_Trooper
    @7th_CAV_Trooper 3 місяці тому

    There's nothing about the shorter performant version that violates clean code. Seems to be a lot of confusion created by people who didn't comprehend the book.

  • @speedychicken831
    @speedychicken831 2 місяці тому

    Just WOW! You've killed OOP, sir.

    • @poguri27
      @poguri27 2 місяці тому

      It's really not as simple as this guy makes it seem. He's yet another noisy online programmer who thinks he's the god of programming and thinks he's qualified to write off entire swaths of software development without actually understanding them sufficiently. He's spreading overconfidence and close mindedness and you've fallen for it.

  • @rogsiel
    @rogsiel 2 місяці тому

    I will be sending this video along with Prime's and Casey's videos, to all my friends plagued with the "cool" and "hip" way of writing code. You got a sub from me friend.

    • @poguri27
      @poguri27 2 місяці тому

      People like murarori build their brand on overconfident, nuance-lacking proclamations on the entire programming field and you've fallen for the grift.

    • @rogsiel
      @rogsiel 2 місяці тому

      @@poguri27 Isn't "overconfident, nuance-lacking proclamations on the entire programming field" exactly what such discussions are trying to eliminate? for many years I have seen people building irreversible bad habits, all because this is what person x is saying in their book, and it's in a book so it must be true!

  • @tophat593
    @tophat593 3 місяці тому

    I take your point onboard. I will pick you up on one point. You describe the point as being performance vs onboarding. I don't accept that, I'd argue it's about money. That breaks down into:
    1) The risk of spaghetti code making an unmaintainable / unscalable project where you lose your investment outlay.
    2) Delivering the product while minimising overall costs to the business.
    3) Your project not being beholden to particular devs.
    The bottom line is the asymmetry between the cost of spooling up another server on AWS and devs wages. You're better off throwing efficiency out the window and brute forcing the issue even when that means really quite marginal labour productivity gains.
    An example with pretend numbers: say you have 10 devs on a project for 100 days who earn $500 a day. Half a million cost. Say an unperformant codebase takes 5 days off the completion. That's £25k. How much computing can you buy for $25k? More than enough is the answer. I just realised I did that maths in my head which is tempting fate... Regardless, silicone is cheap, meat isn't is my point.
    The difference between gaming and websites isn't so much the user tolerance (it obviously is that too) but the fact that you can scale hardware on a website if you want it to load quicker but you're stuck with the user's gaming rig.

    • @eduantech
      @eduantech 3 місяці тому

      The moment speed becomes an issue, you need to rewrite the whole thing in a performant way (hotspot optimization doesn't exist, according to the optimization experts I've heard talk about it), so you end up paying for it double.

    • @eduantech
      @eduantech 3 місяці тому

      What I said notwithstanding: I think the smaller version, in this case, is easier to read.

    • @tophat593
      @tophat593 3 місяці тому

      @@eduantech Nah, not the case at all. There's even a famous quote about it: "Premature optimisation is the root of all evil". Even when you're doing a game you focus on productivity, getting it out the door (obviously you avoid doing stupidly / needlessly expensive things) then when you're done you find the bottlenecks and optimise those. Usually there's just a few functions that take most of the load. The whole point of modelling and clear is that the structure is maintainable and expandable.
      Google has the saying "Python with we can, C++ when we must". That's the same thing but with languages. That's to say you just use performant code at a few select points.
      Plus, as I say, you can just hardware yourself out of trouble at a fraction of the cost. Compute is dirt cheap.

    • @tophat593
      @tophat593 3 місяці тому

      @@eduantech Oh absolutely. Anything more than a little function for such a simple task would have been overkill. I'd write the same thing myself all day of the week.
      But the dude made the point himself, if you wanted to scale this - especially if you didn't know how it was going to be scaled - then what are you going to do? You're going to make classes/structs and you're going to model it.
      Thing is though, I don't want to pick apart to much the specific example he gave because you can always do that and it's not constructive. I just wanted to make a general point about the rationale for the standard approach.

    • @etodemerzel2627
      @etodemerzel2627 3 місяці тому

      To me, "clean" code is a barely readable mess.