3 More Laws of Writing Readable Code

Поділитися
Вставка
  • Опубліковано 21 жов 2024
  • Is your code readable? Or is it difficult to understand? Following these three laws will help you to become the guy that every Engineer wants to be on the same team with because code reviews become so easy!
    _________________________________________________________________________________________________
    If you want to be a part of our community, join our Discord!
    👉 / discord
    Thank you for being part of the community! ❤️

КОМЕНТАРІ • 162

  • @kantancoding
    @kantancoding  2 дні тому +1

    Click here to Land Your Dream Job! Become a Microservice Expert With This Hands-On Golang Course 👉 kantancoding.io

  • @fsharpfan
    @fsharpfan 11 днів тому +236

    A builder to create a simple object? No! Just use named arguments instead of positioned arguments. If your language does not support them, then maybe you need a builder. Creating a builder takes time!

    • @spicynoodle7419
      @spicynoodle7419 11 днів тому +21

      Creating procedures also takes time. Let's write everything in main

    • @TeverRus
      @TeverRus 10 днів тому +30

      Named arguments are the best! Seriously, why write more code if you can write less code?

    • @trwn87
      @trwn87 10 днів тому +6

      Not all languages have named arguments though!

    • @TeverRus
      @TeverRus 10 днів тому +17

      @@trwn87 Screw those languages that don't have named arguments! (jk)

    • @trwn87
      @trwn87 10 днів тому +5

      @@TeverRus To be honest, kind of true... Except there is a good alternative, of course!

  • @i_isak1451
    @i_isak1451 9 днів тому +19

    for anyone worried that using const variables will be worse for performance since you need to create variables for values now. First of all most compilers will substitute const variables for a set value anyways and is used exactly as if you just typed the number instead. Its a win win. Secondly, you should not do premature optimization anyways since it will make your code way harder to read, maintain, refactor and change later down. Only optimize when needed, prioritize more readable code before that.

    • @kantancoding
      @kantancoding  9 днів тому +4

      Good point. Also should mention that in most cases, people won’t be needing to min max performance like this in modern applications anyways. There are many situations where readability is more important.

    • @halvarf
      @halvarf 8 днів тому +6

      Context is important for that general rule. It's clearly true for your standard business and web applications, but if you are on a microcontroller or in your main game loop, you have to think about what you're doing to the compiled code. Constants are no problem anywhere of course.

  • @Kebabrulle4869
    @Kebabrulle4869 10 днів тому +37

    For the last example, I would use keyword arguments (python) instead. Like createUser(name="Alice", age=30, ...). Less bloated and just as clear, and on top of that the order of the arguments doesn't matter.

    • @ktz1185
      @ktz1185 9 днів тому +3

      That's exactly what I was thinking!

    • @kantancoding
      @kantancoding  8 днів тому +6

      Yeah, would be great if all languages had that 💯

  • @derechtepilz
    @derechtepilz 7 днів тому +11

    The last point is a non-issue if you use a proper IDE. For example, I mainly code in Java using IntelliJ and if I encounter a function requiring many parameters I can press Ctrl+P and I get a tooltip displaying which arguments to pass and where.

  • @JProgrammingTech
    @JProgrammingTech 11 днів тому +8

    Thanks man, sometimes my codebases get very chaotic, these really help

    • @kantancoding
      @kantancoding  11 днів тому

      Yeah man, me too! Thanks for watching 😊

  • @sealsharp
    @sealsharp 8 днів тому +26

    I really dislike the common wisdom about "self-documenting code" as it is proven again and again by examples that are the simplest of simple code.
    I think it all starts somewhere different. And that's the distribution of logic into multiple methods when it does not need to be that way.
    When ever something gets so big that you might add in a comment, someone will say "just split it into descriptive methods", and yes, in the spirit of uncle bob you can split that 30 lines method into 10 simple methods. And instead of reading the code from lines 30 to line 60, the dev now has to scroll around trying to memorize 10 methods and what they do and build a mental model of how they are called. And after splitting one method into 10 methods, it's suddenly too much work to put a doc header of them, so we don't do it because we don't like tying shit after we just split that shit up for no reason.
    Three steps back. Lets not split up code if there's no reusing of the methods. Let's keep the code local, in context.
    Complex code exists, because complicated tasks exist.
    So you got complex code. Your coworker asks "what dos that do?"
    What do say? Do you go line by line saying things like "so this line checks if the first parameter is null" and so on? Of course not. Your coworker can read. Human language can is great to explain the concept of something. You will probably be able to formulate one sentence that can explain a complex block of code. Well, if you understand that code you should.
    And that's a good comment. Because three years later, someone will search for a bug and will find that block of code and ONE GOOD LINE may explain it better than anything else.
    "So what if the comments lie?"
    Comments are written with the assumption that code does what it is meant to do. Comments may "lie" when the code does not what it is meant to do, but in that case, the bug is the discrepancy between intended and actual behavior. You got two versions now, one telling you what it does, and one what it is supposed to do. You can now check if the assumptions where wrong from the beginning or if it's an implementation error and the fix is going to make the code do what the comment tells.
    That's my experience in working with complicated code.

    • @kantancoding
      @kantancoding  8 днів тому +2

      Yeah, you make some good points but like with everything there is a balance to be found. When I say to write self documenting code.. it doesn't implicitly mean that you should NEVER write comments.

    • @genechristiansomoza4931
      @genechristiansomoza4931 3 дні тому +1

      Comments should be used to tell why a certain code is there, especially for complicated logic, not what the code does.
      It does not hurt to have a private method that is not reused. It's pupose is to only split logic at this point.

    • @jfftck
      @jfftck 2 дні тому

      If you can't write a simple name for what your code is doing, then it is more than likely hard to test, and that is the biggest code smell. I have been coding for over 15 years professionally, and have seen requirements change and comments still reflect the original intent, so in those cases, it is a lie on what is expected. I think it is more important to comment external APIs so you don't need to go back to the service provider's website, or you would be able to refer to older implementations when a provider breaks the contract that was given when you started using the service and would have legal grounds to ask for compensation for any losses due to service failures.

    • @jfftck
      @jfftck 2 дні тому

      @@gearboxworks If you think comments are good, that is fine, but to say that comments are going to lead to better understanding of the code is being hopeful that the person who wrote it is able to express themselves in a completely understandable manner. My experience is that those same people write bad comments. Have you worked for a foreign company? You will quickly abandon comments and read the code to understand what is happening.
      It would be great if everyone could write comments that are perfect for every function, but I have experienced the exact opposite and have learned to distrust them.

    • @mrwensveen
      @mrwensveen День тому

      Splitting up long and complex methods works best when you can create simple and functions that make sense on their own. Preferably these functions are pure/static, i.e. they don't change anything of importance for the calling method. Now, you don't have to scroll around anymore because the main method remains in control of the method's flow and of the object's state (if any).

  • @Biriadan
    @Biriadan 9 днів тому +7

    Not a fan of all that mutation with the builder. I’d just create the structure literal as an argument and pass that. No need for the user variable or any setter functions.

    • @kantancoding
      @kantancoding  8 днів тому +1

      Good point but it depends on the langauge. In many languages you'll run into the same issue with lots of constructor params.

    • @eturnerx
      @eturnerx День тому +1

      In Typescript, I'd use a or a type that enforced mandatory properties and made anything with a sensible default optional.

  • @kenye3057
    @kenye3057 9 днів тому +32

    When I read the legacy code , developers always give bad long name to the magic numbers, making the code more difficult to read.

    • @kantancoding
      @kantancoding  8 днів тому +3

      🫠 yeah naming can be difficult!

    • @halvarf
      @halvarf 8 днів тому +2

      OTOH, developers who have trouble naming things tend to not be better at writing clear comments either.
      In the cases where the variables are only for documentation of otherwise magic numbersin the code, it can also help to put the definition and value assignment near to the point there the variable is used so you don't have to scroll around when reading.

    • @pepperdayjackpac4521
      @pepperdayjackpac4521 4 дні тому +1

      can u give an example of a bad long name of a magic number?

    • @Grif_on96
      @Grif_on96 3 дні тому

      @@pepperdayjackpac4521
      MONSTER_LANTERN_BURN_RAYCAST_LENGTH (constant) and concat_struct_of_structs_in_to_underline_separated_string (function) are some examples of my lengthy namings .
      And yes , this is from my code in commeriacl game :)

    • @jfftck
      @jfftck 2 дні тому

      I would expect no better when writing comments, so what is your point? It is the whole point of code review, if the reviewer has to be told what the magic number is, or they figure it out by reading the code, it means that it should be pointed out to be renamed. This is the failure in your team, you must look out for the next developer and not rely on current knowledge.

  • @FlailingWildly
    @FlailingWildly День тому

    Excellent advice.
    I disagree with the people who say that “self documenting code is a fallacy“. Code (small bits of functionality) can definitely be made self documenting - meaning that you should be able to understand what the function is doing by writing the code in ways that are clearer and more descriptive. However, this is not the same thing as saying “comments are bad.“ It’s not that the comments are bad, but rather that since comments are nonfunctional, it can be easy for them to fall out of step with the actual code. Comments are helpful, but they also have a built-in maintenance cost. There is definitely a place for both. If the function is complex, and cannot be easily subdivided into multiple smaller functions that are easier to understand, then yes, definitely provide well written comments for future developers.
    “Self documenting projects” are definitely a fallacy. README and CONTRIBUTING are critical documents for every repository.

    • @kantancoding
      @kantancoding  День тому

      Couldn’t have said it better myself. I finally found the time to respond in that thread where the person said the thing about it being a “fallacy” but not sure if it will do any good

  • @erichlf
    @erichlf 9 днів тому +22

    Missing doc strings... I get that you don't want too many comments, but I shouldn't have to read the code to know what a function's effects, return types, or exceptions are.

    • @chillie_dude
      @chillie_dude 8 днів тому +12

      Depends. On library always document functions.
      For applications don't because the cost is high to maintain such comments and they very often get out of date. Any modern IDEs can show the input/output automatically. And yes it's less detailed than comments but again for apps it's not worth and get out of date often.

    • @erichlf
      @erichlf 8 днів тому +3

      @@chillie_dude I'm used to developing with plenty of people that don't have a clue why a function exists, so documentation makes it where I'm answering less questions.

    • @vlc-cosplayer
      @vlc-cosplayer 8 днів тому +2

      "All my functions are less than 10 lines bro, just read them bro" 💀

    • @chillie_dude
      @chillie_dude 7 днів тому +2

      @@erichlf well it's an interesting problem but I'm not convinced just commenting every function is the only solution. if a function is tricky then yeah great go ahead.
      Are the people not used to read code ? It's a skill to learn and an important one, you should ask them to try more.
      Is your code itself clear enough. Removing magical variables, better function name, explicit variable names, smaller (but not too small!) functions etc. Can help a lot too.
      So a mix of some comments, more reading and cleaner code might help. Just adding comments, which increase cost of maintainance and likelihood of being wrong, might not be the only solgion

    • @erichlf
      @erichlf 7 днів тому +4

      @@chillie_dude i would say not updating comments is a problem. And should be addressed. Also docstrings shouldn't be so specific that they need to be updated, since they shouldn't explain the code. If you're changing a function in such a way that the doc string is changing you're probably doing something you shouldn't do.

  • @steampunkWizardStudios
    @steampunkWizardStudios 7 днів тому +1

    Use "Keyword arguments" or "destructuring" for the last one.
    If you use something like TS make the parameter a type interface.

  • @ego-lay_atman-bay
    @ego-lay_atman-bay 8 днів тому +6

    3:23 Except python allows named parameters, allowing you to pass in parameters in any order, just by using it's name. I'm just saying, if you're writing in python, you can use named parameters instead. Oh, and you can also force parameters to be named or positional.

    • @kantancoding
      @kantancoding  8 днів тому +1

      Yeah! That’s a good observation. Python is great 😊

  • @NickBrown79
    @NickBrown79 4 дні тому

    These are GREAT!!! keep em coming!!

  • @SmoMo_
    @SmoMo_ 9 днів тому +1

    Nice video, and I know this isn’t at all relevant to the coding points you were making..,,
    ,,,but that’s not how tax thresholds normally work.
    You would you the lower tax until the threshold is met and then the higher tax rate on what is left.
    Otherwise you could increase the price of an item by 1 cent and end up paying massively more in tax suddenly .

  • @coderwolfie2201
    @coderwolfie2201 10 днів тому

    Useful advice. the awkward silence at the end though.

  • @kevintanudjaja7597
    @kevintanudjaja7597 10 днів тому +16

    so function createUser will create a user with a user that is already created?

    • @kantancoding
      @kantancoding  10 днів тому +7

      Hmm, no. By create user I mean actually persist the user. You’ll have to use your imagination for the logic in the function since I didn’t want to convolute the example with implementation details.
      An easy way to imagine it is that the user object in our code is different from what’s in the db. So maybe in the logic some ORM is used

    • @kevintanudjaja7597
      @kevintanudjaja7597 9 днів тому +2

      Ah I get it now. So this createUser func is an interface of SQL insert to a database. I thought it's a constructor for user struct in memory, so that's looks like inception to me.
      The builder itself is the one that will replace user "constructor" (Need to create it manually in go, because go don't have classes) of having too much parameter. Thanks for sharing

    • @kantancoding
      @kantancoding  9 днів тому +1

      @@kevintanudjaja7597 yes you've got it! And thanks for always supporting :)

    • @vlc-cosplayer
      @vlc-cosplayer 8 днів тому

      Django ORM has both "create" and "save", and they almost do the same thing 💀
      It may be better to name it insert() (maybe with a bool "update" parameter that turns it into an upsert), so the intent is clearer.

  • @Naveh_O
    @Naveh_O 9 днів тому +1

    I would argue that the second example needs some readable function for the logic of the tax ratio - that way the two bits of logic are separate. There's the calculation of the tax percentage, and there's the calculation of the tax value itself:
    func calculateTax(price float64) float64 {
    float64 taxRatio = calculateTaxRatio(price);
    return price * taxRatio;
    }
    func calculateTaxRatio(price float64) float64 {
    if price > priceThreshold
    return highValueItemTax;
    return lowValueItemTax;
    }

    • @timgerk3262
      @timgerk3262 9 днів тому +2

      Being literal, calculation of tax is what the greybeards call a Business Rule. The logic comes directly from real life, and should be unitary (not broken up.) Because we know that taxes go up periodically and vary from place to place, also take care that extrinsic business rules are somehow externalized, such as by dependency injection or service discovery.

  • @JeffersonPires90
    @JeffersonPires90 18 годин тому

    I've finally found someone else using Agave font face :)

  • @apmcd47
    @apmcd47 4 дні тому

    Well, you should be using a docstring of some sort to document your code (javadoc, python docstrings, doxygen). Code reviews should pick up unaltered docstrings. Personally I don't want to read a function to find out what it does, that is what the docstring is for. I want to read it to find out how it does what it does.
    Too many parameters? As other have said, if your language has named arguments, use those. If not, and it has dicts/hashes, use them instead, although I suppose that is a sort of a builder. But even when using named arguments, a style-guide enforcer could complain of too many arguments.

  • @fabricio-t7x
    @fabricio-t7x 4 дні тому

    Another approach is to just ask for a struct with the required fields. The caller can instantiate the struct before calling, or on call, and (AFAIK) unless you instantiate a struct with all fields in order, then the compiler will have you specify field names. So it ends up being like a builder object, but built into the language and with no bloat shenanigans.

    • @kantancoding
      @kantancoding  2 дні тому +1

      Great point! Yes, Go allows us to be explicit when creating struct literals so you are 100 percent correct.
      This tip is more geared towards non Go devs. For example in Java you’d need a class constructor with a bunch of params same as the createUser method.

    • @fabricio-t7x
      @fabricio-t7x День тому

      @@kantancoding What the Java! lol
      jokes aside, i'm of the opinion that the java person should learn the go way, not the other way around. 🤣

    • @kantancoding
      @kantancoding  День тому

      I’m of a similar opinion bro. The Java person should quit their job and learn Go.

  • @kucingoyen1
    @kucingoyen1 5 днів тому

    Creating a new object for User is good, but I calling that using Builder is just ugly. You can miss some variables to be updated when we alter the object even if we have default value (in most cases).

    • @kantancoding
      @kantancoding  2 дні тому

      I see where you’re coming from but depends on the builder. You can add some validation for required fields.

  • @donnewmancanada
    @donnewmancanada 6 днів тому

    I used to agree with the last one, but have gone back to separate arguments. Developers tend to be lazy so they would re-use existing generic classes and just keep adding properties they needed instead of passing an object with only the parameters needed for the method call. It also prevents overloading resulting in a method full of if statements. Lastly, in a well-architected n-tier application a layer should decouple its dependencies which results in the need for mapping objects between layers.

    • @kantancoding
      @kantancoding  5 днів тому

      Hmm, some good points here but in an n-tier architecture it’s imo much easier to map objects between layers as opposed to trying to aggregate params between layers. You can also have common classes between layers depending on the overall design. Either way there’s going to be some decisions that need to be made based on the business requirements.
      I’d also argue that this type of architecture shouldn’t be referred to as inherently “well-architectured.” I’ve seen architectures like hex arch/ports and adapters as well as onion bloat simple applications with infrastructure that added no benefit. Just made the project more difficult to maintain and made it harder for devs to onboard.
      Anyways, I love your comment. Thank you

  • @champx549
    @champx549 8 днів тому

    could you make a tutorial on how to make a builder? you've got me curious on how to make those

    • @kantancoding
      @kantancoding  7 днів тому

      I already have one somewhere :) I think you can just search in my videos for builder design pattern

    • @champx549
      @champx549 4 дні тому

      @@kantancoding Alright! I shall have a look.

    • @champx549
      @champx549 4 дні тому

      @@kantancoding the funny thing is... I actually searched up builder patterns after watching this video. The first that got recommended was yours. Without realizing it I watched and when I checked your videos right now I saw the same video 😂

  • @sad_man_no_talent
    @sad_man_no_talent 6 годин тому

    3rd one recommendation use typescript interface

  • @vrmeup
    @vrmeup 8 днів тому

    Great advice, thanks 😃

  • @jfftck
    @jfftck 10 днів тому +1

    The last example could be solved with having multiple objects that represent the type of each and passing those in, no need for a builder. The added value of this, when a new requirement to add more values, you can add to an existing object or create a new one, depending on how that value is related to existing ones. For example, take the address value, what happens when you get a new requirement that states that the house number should be separate from the through way name? If you have an object represent the value, then you can just split them and add a method to return the full address.

    • @Betadesk
      @Betadesk 9 днів тому +3

      So create 5 classes just to wrap primitive values instead of 1 builder class? That seems like a lot of overhead

    • @jfftck
      @jfftck 9 днів тому

      @@Betadesk I didn’t say to make classes, structs are smaller and many languages can add methods to them and, if you’re using a language that doesn’t, you can use a function that you pass the struct into. It would add a type to a primitive and also add context.

    • @kantancoding
      @kantancoding  8 днів тому +1

      These are very good points and it is a good alternative but it depends on the context in my opinion.
      Like @Betadesk mentioned, creating 5 structs to wrap primitive types might be cumbersome. It really depends on if that type of design would benefit the overall architecture which can’t really be determined in the small example I provided.

    • @jfftck
      @jfftck 2 дні тому

      @@gearboxworks If you don't understand the power of types, then you need to research how newer languages are using them. This is a way to avoid hidden bugs from getting into your system. I agree, in a perfect world, we would not need all of this, but I have seen multiple times where null pointers cause an error due to incorrect values are passed due to not utilizing types. One thing to keep in mind is not all languages have powerful typing systems, and anything that can help that is good.

  • @TizzyT455
    @TizzyT455 2 дні тому

    That last example didn't make any sense to me. If the original createUser function was used to create a user, and you instead put a builder in its place, whats the point of passing in an already created user into a createUser function?

    • @kantancoding
      @kantancoding  2 дні тому

      Yeah, lots of people confused about this. The createUser function creates the user in the database

  • @ErikBongers
    @ErikBongers 7 днів тому

    A builder likely comes at a runtime cost. Use with care.

  • @saiuan4562
    @saiuan4562 3 дні тому +1

    Wait what? A method that builds a user, but its signature requires a user? The heck?

    • @kantancoding
      @kantancoding  3 дні тому

      The method doesn’t build a user. It creates a user in the database.

  • @djteejay87
    @djteejay87 7 днів тому

    Creating a user struct to create a user 😂 Brilliant.
    Almost all modern languages support named parameters, this approach would be way clearer than the one explained.
    The other two pieces of advice are good ones though.

    • @kantancoding
      @kantancoding  6 днів тому +1

      I think you’re confusing persisting a user and creating a user object in the application as being the same thing. Hope it helps! 😊

    • @djteejay87
      @djteejay87 5 днів тому

      @@kantancoding I understood what you were doing there, for me it's not worth to create that User class/struct. If you are working with an ORM, maybe you can use a mapped entity of the Users table.

    • @djteejay87
      @djteejay87 2 дні тому +1

      @@gearboxworks I would not create an object with a builder anyway. I'd rather create a lightweight structure/class just for the sake of passing around those params. And I would only create it if the context you described applies.

    • @whydoyouneedmyname_
      @whydoyouneedmyname_ 2 дні тому

      I agree he should have mentioned named parameters, but we're using Golang as an example which doesn't have them, almost every startup nowadays uses a Go backend so thats perfectly reasonable

  • @ericmintz8305
    @ericmintz8305 7 днів тому

    Floating point cannot represent money accurately because you cannot represent 1/10 as a finite sum of powers of 2. Use an accurate representations like an integer containing the smallest unit (e.g. cents, pence) or a fixed point decimal type. Uncontrolled round-off errors are almighty difficult to diagnose and even harder to fix.

    • @kantancoding
      @kantancoding  7 днів тому

      Yeah you’re right but It is not a real application. Don’t have time to explain that 10000 cents is 100 dollars and doing so would convolute the actual point I’m trying to explain.

  • @LBCreateSpace
    @LBCreateSpace 11 днів тому

    Great advice Ty!

  • @Linuxdirk
    @Linuxdirk 3 дні тому

    Thje formula used in the first example actually is pi * r * r and not pi * r^2. While the result is the same, those are two different formulas.

  • @madbanana22
    @madbanana22 2 дні тому

    but how do you use the classBuilder without a classBuilderBuilder??

  • @mumcarpet109
    @mumcarpet109 11 днів тому +1

    Amazing 🎉

  • @ФедорУсов-м9ш
    @ФедорУсов-м9ш 10 днів тому

    3rd rule -> You are clearly breaking 1 entity (method call) between two lines. Never seen code style like this before:
    a().
    b().
    c()

    • @DaKeypunchAr
      @DaKeypunchAr 10 днів тому

      You'll return the object at Every call lol

    • @kantancoding
      @kantancoding  9 днів тому +1

      Not really sure what the question is here 😂

    • @kevintanudjaja7597
      @kevintanudjaja7597 9 днів тому +1

      It's called fluent interface, or method chaining

    • @DaKeypunchAr
      @DaKeypunchAr 9 днів тому

      @@kantancoding he's like how are you calling a method to void but you're surely not

  • @skelaw
    @skelaw 5 днів тому

    Last point is useles eg for js/ts. Just pass an object.

    • @kantancoding
      @kantancoding  2 дні тому

      You still have to create the instance of the object using the class constructor with the same amount of params. So you’d just move the problem to the constructor.
      Unless I’m mistaken (it’s been a while) JS/TS doesn’t support named params.

  • @Kokurorokuko
    @Kokurorokuko 5 днів тому

    Why would a function called createUser accept an instance of User?

    • @kantancoding
      @kantancoding  5 днів тому

      The instance of user is in the application memory. when calling createUser the user is persisted to disk e.g. a database

  • @asagiai4965
    @asagiai4965 11 днів тому

    1st of all in the first question yes. Remember guys these are two different developers. So the validity of the code still true as long as the next developer is giving the val8d code.

  • @Vlad1998996
    @Vlad1998996 10 днів тому

    these are very good videos :)

    • @kantancoding
      @kantancoding  8 днів тому

      Glad you like them! Thanks for watching!

  • @igboman2860
    @igboman2860 3 дні тому

    I mean go isnt really design for the user business. Why not create a struct without the abstraction

    • @kantancoding
      @kantancoding  3 дні тому

      It depends on the language. In Go you can create a struct literal and be explicit when setting the fields but this video isn’t Go specific.
      In Java for example, to create an instance of the user you’d need to use the class constructor which would have the same problem with the params as the create user function.

  • @akam9919
    @akam9919 9 днів тому +1

    Readable code, schmedable code. Make updated comments a requirement before code gets merged. Yes, comments can lie, but so can variable names, which objectively are just memory addresses with built-in comments. Their names are not for the computer, they are for you the developer. Make comment changes part of code review. You could create a function just like the one at the beginning, but if there is no circle that needs it's area calculated but some thing else that has a virtually identical formula, is the code really self-documenting? If we are okay with updating variable and function names, updating comments should be no different. Ontop of that, If I have a game that has 30 enemy types, and each attack pattern is created by a function, should I change each function name to "consecutiveNormalPunchesAttack" or "falconSmashAttack"? What if each has to conform to an interface? Should I make a private function that has the sole purpose of documenting what the attack is supposed to be like? Perhaps if there is some extra special logic, such as randomly chosen attacks that each have their own complex logic, but if I have a 20 simple enemies that basically have only simple but unique attack function, I think making extra and redundant functions is only going to make a file longer, bloated, and harder to follow. I'd rather have a clear comment that explains what the code is supposed to do, which is what the real purpose of comments is. It isn't about what the code does, it's why it's there.

    • @alexaneals8194
      @alexaneals8194 8 днів тому +2

      Commenting is essential to code maintenance and yes they should be updated; however, comments should never describe what the code already does. Comments should include why the code was written or to encapsulate the code so the developer does not need to look at the code to use it. A comment like "x + y = z" is useless and redundant; however, a comment stating that we need to add such a such function to comply with a business or regulatory requirement warns the dev to not change the code unless that business or regulatory requirement is changed or there is an error in complying with that requirement as the code is currently written.

    • @gariannobinger9933
      @gariannobinger9933 7 днів тому

      These posts are good advice.

  • @shanewolff94
    @shanewolff94 5 днів тому

    What is the font used in the video?

  • @gariannobinger9933
    @gariannobinger9933 7 днів тому +4

    "self documenting code" is a fallacy. Comments are not bad, they are necessary. Are they redundant with the code? They can be, but that's a good thing. Why? Because they provide a layer of confirmation, whereas code all by itself may be correct or may be wrong. Without the comments, there's no way to compare what a function was _intending_ to do (the comments), verses what it _actually_ does (the code). The problem in this video's example isn't that there were comments, its that the later developer was lazy and didn't update the comments, which is a bad developer.

    • @kantancoding
      @kantancoding  7 днів тому +2

      Tests should provide your layer of confirmation. Not comments. Otherwise there’s so way of knowing which is wrong, the comment or the code.
      Also, I’m not arguing that all comments are bad/wrong. I’m arguing that self documenting code can eliminate the need for most comments which means that when you do actually need to write comments, they are actually useful as opposed to just being redundant noise.
      Also, I don’t think that the dev that didn’t update the comment is necessarily bad. Many factors go into why a dev might not update comments. I’ve seen comments written so poorly that I couldn’t even understand what they were trying to explain therefore updating them was impossible.

    • @gariannobinger9933
      @gariannobinger9933 5 днів тому +3

      @@kantancoding What I was saying is that comments provide "a" layer of guidance and confirmation, not "the" confirmation. Yes certainly, there should be test cases. But in practical terms, the struggles around not knowing which is wrong, the code or the comments/tests is still valid in both paradigms, whether you're taking about comments or tests cases.
      Either way, when the bug report comes in, someone has to find the bug. When reading that code and wondering "hmm is this < supposed to be a

    • @kantancoding
      @kantancoding  День тому

      The struggle around not knowing which is wrong 「the comments or the code」 or 「the tests or the code」 is certainly not equally valid in both paradigms.
      The most obvious reason being that comments are far easier to overlook than tests. In most cases, if tests are wrong, your ci/cd pipeline breaks.
      In the rare cases that a unit test is written in such a way that it’s wrong but still able to pass, it’s still part of a test suite and some integration test will likely break even if that unit test is somehow passing.
      So the odds that multiple tests that depend on some core business logic are all able to somehow pass even if the tests are wrong are far lower than the odds that some random fragile comment is neglected or simply incorrect.
      There are really no checks and balances in place for comments other than the reviewers eyes..
      and your whole argument is that good devs don’t miss these types of things but that, my friend, is the REAL “fallacy”

  • @JProgrammingTech
    @JProgrammingTech 11 днів тому +1

    How do you edit your videos? I wisg mine looked so clean

  • @atabac
    @atabac День тому

    as long as its english, code is readable to me😂 assembly is very readable

  • @cryptonative
    @cryptonative 11 днів тому +4

    hate comments in general, only reasons I comment is about a strange edge case or to separate code blocks in sections given a larger function
    not sure I agree on the 3rd one, a proper lsp can help demostrate what each argument represents

    • @МаксимГорюнов-м7и
      @МаксимГорюнов-м7и 10 днів тому

      What do you mean by lsp?

    • @romanpolishchuk4517
      @romanpolishchuk4517 10 днів тому

      ​@@МаксимГорюнов-м7иcode suggestions

    • @cryptonative
      @cryptonative 10 днів тому +2

      @@МаксимГорюнов-м7и “language server protocol”, more specifically about something called “inlay hints” which shows the types and names of function arguments

    • @МаксимГорюнов-м7и
      @МаксимГорюнов-м7и 10 днів тому

      @@cryptonative this is probably a level I haven't gotten to yet, thank you, I will look into it deeper

    • @suibora
      @suibora 8 днів тому

      @@МаксимГорюнов-м7и LSP is already standard in most code editors. When you try to call a function in VS code or nvim, it will show you a preview, or 'hint' of the arguments and types that the function takes

  • @KlausBayer390
    @KlausBayer390 10 днів тому

    Which programming language is this? go?

  • @madbanana22
    @madbanana22 2 дні тому

    2:25 THATS THE SAME THING AS USING COMMENTS???

  • @AlfredLotsu
    @AlfredLotsu 3 дні тому

    the devops playlist is gone

    • @kantancoding
      @kantancoding  3 дні тому

      Hey bro. There's good news and bad news about that playlist. If you want more information feel free to DM me on Discord.

  • @THEShAdOwHFV
    @THEShAdOwHFV 10 днів тому +1

    That s come clean code rules to keep your code elegant, good job*

  • @lucemiserlohn
    @lucemiserlohn 7 днів тому +2

    Method chaining, really? I thought Java demonstrated very well why NOT to use that crap.

  • @coder_one
    @coder_one 10 днів тому +2

    The slogan "Write self documenting code" stands in contrast to the fact that for some reason, most Go programmers (including the language's creators) write code in such a way that most variables are meaningless, unreadable 1-3 letter "words"; functions are also exaggeratedly called abbreviations as if Go programmers were deducted from their paycheck for every letter in the code.
    Therefore, it should be made clear - idiomatic Go is often a contradiction of "self documenting code."

    • @alexaneals8194
      @alexaneals8194 8 днів тому +2

      Self-documenting code is impossible. Code can only tell you what it is doing not why it was written. Most cases that I have run into where a dev has really screwed something up is not because they could not understand what the code was doing, but rather they didn't realize why the code written that way. A function returns null and the dev assumes that the function has a bug and changes the function to not return null and crashes a completely unrelated system. An address space is not initialized and a dev assumes that it's a bug and makes sure to initialize the space only to compromise the encryption algorithm (this occurred in a linux router software update that created an exploit).

  • @venusearth6682
    @venusearth6682 11 днів тому

    🙌🏽🙌🏽❣️

  • @user-tk2jy8xr8b
    @user-tk2jy8xr8b 9 днів тому +1

    The last problem is easily solved by typing. Instead of practicing primitive obsession and using raw strings, wrap them. This way it'll be impossible to accidentally swap the arguments and have the code still compiling after that.

    • @LittleLily_
      @LittleLily_ 2 дні тому +1

      Having different types would definitely help in the case shown in the video and most other cases, but there are situations where a function does actually accept multiple values of the same semantic type, such as multiple names, or multiple ages (such as to calculate who is older), etc. In those situations you usually only have two values of the same type though so it's not too bad, and if your language supports named arguments then that would be the best solution in those specific cases.

  • @МаксимГорюнов-м7и
    @МаксимГорюнов-м7и 10 днів тому

    The last one can be avoided if different fields have different types. Overkill? NO! Useful type system