3 More Laws of Writing Readable Code

แชร์
ฝัง
  • เผยแพร่เมื่อ 23 พ.ย. 2024

ความคิดเห็น • 238

  • @kantancoding
    @kantancoding  หลายเดือนก่อน +3

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

  • @fsharpfan
    @fsharpfan หลายเดือนก่อน +383

    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 หลายเดือนก่อน +51

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

    • @TeverRus
      @TeverRus หลายเดือนก่อน +50

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

    • @trwn87
      @trwn87 หลายเดือนก่อน +10

      Not all languages have named arguments though!

    • @TeverRus
      @TeverRus หลายเดือนก่อน +26

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

    • @trwn87
      @trwn87 หลายเดือนก่อน +7

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

  • @i_isak1451
    @i_isak1451 หลายเดือนก่อน +62

    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  หลายเดือนก่อน +11

      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 หลายเดือนก่อน +9

      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 หลายเดือนก่อน +63

    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 หลายเดือนก่อน +3

      That's exactly what I was thinking!

    • @kantancoding
      @kantancoding  หลายเดือนก่อน +11

      Yeah, would be great if all languages had that 💯

  • @fakharraza9235
    @fakharraza9235 5 วันที่ผ่านมา

    1. Write self-documenting code
    2. Avoid magic numbers (assign variables to numbers for a dynamic approach)
    3. Avoid too many function parameters (if confusing)

  • @JProgrammingTech
    @JProgrammingTech หลายเดือนก่อน +11

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

    • @kantancoding
      @kantancoding  หลายเดือนก่อน

      Yeah man, me too! Thanks for watching 😊

  • @FlailingWildly
    @FlailingWildly หลายเดือนก่อน +2

    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

    • @darrennew8211
      @darrennew8211 24 วันที่ผ่านมา

      I instituted a rule in my team that every directory's first check-in has to be a README file. Some of them were pretty stupid, but most of them came out pretty well, and I got kudos from a couple of co-workers for slowing them down and making them think for five seconds what they were doing before jumping into a new part of the project.

  • @Biriadan
    @Biriadan หลายเดือนก่อน +16

    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  หลายเดือนก่อน +4

      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 หลายเดือนก่อน +2

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

    • @oli_dev
      @oli_dev 29 วันที่ผ่านมา

      I was looking for this exact comment. This is what I do all the time, its super nice

  • @steampunkWizardStudios
    @steampunkWizardStudios หลายเดือนก่อน +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 หลายเดือนก่อน +10

    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  หลายเดือนก่อน +1

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

  • @derechtepilz
    @derechtepilz หลายเดือนก่อน +19

    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.

    • @NickCombs
      @NickCombs หลายเดือนก่อน +2

      Best practice not to assume the next person is using the same or similar tool.

    • @derechtepilz
      @derechtepilz หลายเดือนก่อน +2

      @@NickCombs In no sentence have I said that I do it or that you should just not care about it. I just said how I'd deal with it.

    • @NickCombs
      @NickCombs หลายเดือนก่อน +1

      If it's working, more power to you. I'm just chiming in in case someone else is thinking about leaning on the IDE in a more typical situation.

    • @darrennew8211
      @darrennew8211 หลายเดือนก่อน +3

      @@NickCombs The likelihood you're writing a function like "createUser" and not using an IDE is vanishingly small.

    • @NickCombs
      @NickCombs หลายเดือนก่อน +1

      @@darrennew8211 No it's not. Text editors, CLIs, remote servers, and deployed apps exist.

  • @erichlf
    @erichlf หลายเดือนก่อน +35

    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 หลายเดือนก่อน +18

      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 หลายเดือนก่อน +4

      @@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 หลายเดือนก่อน +6

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

    • @chillie_dude
      @chillie_dude หลายเดือนก่อน +3

      @@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 หลายเดือนก่อน +5

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

  • @madbanana22
    @madbanana22 หลายเดือนก่อน +9

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

    • @sunkittsui7957
      @sunkittsui7957 27 วันที่ผ่านมา

      That's the neat part, you don't

  • @kopsha
    @kopsha 27 วันที่ผ่านมา +1

    These coding rules are great, and they could easily work across most languages.
    Ah, that builder pattern... It’s like a never-ending checklist: set...().set...().set...() - and just when you think you’re done, it’s like, “Surprise! .build()!” As if we haven’t been constructing it piece by piece already. Really, .build(), was that necessary?

    • @darrennew8211
      @darrennew8211 24 วันที่ผ่านมา

      It also makes refactoring harder because any new required thing you add, you have to find all the callers and make sure they're setting it. And the build() is only needed if you're going to return a different type than the builder, which is again unnecessary in OOP.

  • @mra0ul
    @mra0ul 13 วันที่ผ่านมา

    Love the tips. Thank you.
    On the last example, how would you call the create user function?

  • @Naveh_O
    @Naveh_O หลายเดือนก่อน +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 หลายเดือนก่อน +3

      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.

  • @ygstuff4898
    @ygstuff4898 6 วันที่ผ่านมา

    With respect to parameters in a function, using an intelligent IDE (Eclipse, IntelliJ), if the function/subroutine/method is commented to describe the parameters, when writing the code to call the function, the IDE provides prompts for each argument: name/purpose, data type, and parameter position.
    (in Java, this is the power of JavaDoc-style comments)
    Very useful, to a point that programmer's expect to see that, and when they don't....who didn't document/comment correctly?!

  • @kenye3057
    @kenye3057 หลายเดือนก่อน +41

    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  หลายเดือนก่อน +5

      🫠 yeah naming can be difficult!

    • @halvarf
      @halvarf หลายเดือนก่อน +3

      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 หลายเดือนก่อน +1

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

    • @Grif_on96
      @Grif_on96 หลายเดือนก่อน

      @@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 หลายเดือนก่อน

      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.

  • @tkenben
    @tkenben 26 วันที่ผ่านมา

    I suppose if we were to be picky, we would need to say that function is called something even more descriptive - especially considering your updating example with diameter - like "circleAreaByRadius", literally locking in the description of the function and thoroughly documenting it. I guess my point with saying that is, there will always be a line drawn in how self-documenting the code actually needs to be.

  • @yuralis123
    @yuralis123 23 วันที่ผ่านมา

    Something I don't see addressed and I am really curious about is the UserBuilder allowing developers to write bugs. What if the email should not be null. I don't think there is a way to enforce the SetEmail method being called, which could cause weird bugs down the line. A constructor lets you explicitly set if something can be null, and if it shouldn't be null you'll get an error if you don't give a value.
    And for those saying python and javascript doesn't throw an error so it's not always true. There are ways to allow python and javascript to be typed, which will help you find bugs like this, so please use those

    • @kantancoding
      @kantancoding  22 วันที่ผ่านมา

      Hey thanks for the input. As to your concerns, you can simply add validation for required fields in the build() method. Same thing will have to be done with a constructor. There’s no avoiding validation in that case.

  • @coderwolfie2201
    @coderwolfie2201 หลายเดือนก่อน +1

    Useful advice. the awkward silence at the end though.

  • @wsf-t7x
    @wsf-t7x หลายเดือนก่อน

    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  หลายเดือนก่อน +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.

    • @wsf-t7x
      @wsf-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.

  • @leocarmopereira
    @leocarmopereira 29 วันที่ผ่านมา

    Just come across your channel. I love the visual effects!

  • @MandeepSingh-td2ic
    @MandeepSingh-td2ic 16 วันที่ผ่านมา

    Understanding coding can be daunting in the beginning but becomes little understandable later.

    • @kantancoding
      @kantancoding  16 วันที่ผ่านมา

      That’s kind of missing the point imo. I’m not talking about a skill issue of not understanding code here. I’m talking about when experienced devs read code, what code is more annoying to read for example 😂
      You can write code such that the person reading it experiences buttery smooth nirvana 🧈

  • @SmoMo_
    @SmoMo_ หลายเดือนก่อน +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 .

  • @NickCombs
    @NickCombs หลายเดือนก่อน +2

    Many times, a fn with lots of params is built in and not worth making a wrapper just to key the values with an object. In that case, I will give each passed in value a descriptive variable. Even comments are fine there.

    • @kantancoding
      @kantancoding  หลายเดือนก่อน

      Good point. Sometimes it can’t be helped.

  • @Maiuna-yc2uk
    @Maiuna-yc2uk 28 วันที่ผ่านมา

    There is no need for builder in the last case. Use struct literals, it's better, or if your language support named arguments, just use that. A better approach than these two is to use different types (might be overkill though).

  • @jfftck
    @jfftck หลายเดือนก่อน +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 หลายเดือนก่อน +3

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

    • @jfftck
      @jfftck หลายเดือนก่อน

      @@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  หลายเดือนก่อน +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 หลายเดือนก่อน

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

    • @sunkittsui7957
      @sunkittsui7957 27 วันที่ผ่านมา

      @@jfftck Using wrapper types is certainly very useful and robust, but wouldn't a builder object be a good balance between robustness and convenience in more trivial cases?

  • @kevintanudjaja7597
    @kevintanudjaja7597 หลายเดือนก่อน +19

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

    • @kantancoding
      @kantancoding  หลายเดือนก่อน +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 หลายเดือนก่อน +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  หลายเดือนก่อน +1

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

    • @vlc-cosplayer
      @vlc-cosplayer หลายเดือนก่อน

      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.

  • @danielmiller8223
    @danielmiller8223 23 วันที่ผ่านมา

    Issue with your Magic Numbers example. Although I agree with avoiding using magic numbers and even placing the data together in a structure, the problem with your approach is that it created a side effect. My suggestion would be to send in this data to the function or to create the data structure inside the function.

    • @kantancoding
      @kantancoding  22 วันที่ผ่านมา

      Hey thanks for the input! There is no side effect. They are constants.

  • @bigboland6160
    @bigboland6160 24 วันที่ผ่านมา

    first rule is so important. Im almost done my cs degree and ive worked as a grader for many computer classes. so many students hear they need to write comments, and write the most useless redundant comments ever. like legit they will write i = 0; // initializing the variable i to 0

    • @kantancoding
      @kantancoding  22 วันที่ผ่านมา

      Yeah, I get a lot of people advocating for comments in the comments sections of many of my videos. Many of them do indeed seem like students or juniors.
      I’m not opposed to ALL comments but as you mentioned, many people just write useless redundant comments.
      I’m just trying to explain that there’s a time and a place. And usually you can avoid them.

  • @donnewmancanada
    @donnewmancanada หลายเดือนก่อน

    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  หลายเดือนก่อน

      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

  • @sad_man_no_talent
    @sad_man_no_talent หลายเดือนก่อน

    3rd one recommendation use typescript interface

  • @apmcd47
    @apmcd47 หลายเดือนก่อน

    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.

  • @kucingoyen1
    @kucingoyen1 หลายเดือนก่อน

    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  หลายเดือนก่อน

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

  • @ErikBongers
    @ErikBongers หลายเดือนก่อน

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

  • @NickBrown79
    @NickBrown79 หลายเดือนก่อน

    These are GREAT!!! keep em coming!!

    • @kantancoding
      @kantancoding  หลายเดือนก่อน

      Thanks for the feedback! Will do!

  • @TizzyT455
    @TizzyT455 หลายเดือนก่อน

    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  หลายเดือนก่อน

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

  • @ericmintz8305
    @ericmintz8305 หลายเดือนก่อน

    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  หลายเดือนก่อน

      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.

  • @matthewrossee
    @matthewrossee 21 วันที่ผ่านมา

    While I'm a big fan of the builder pattern, I think that the example in your video is bad. The builder pattern shines when one's dealing with creating an object that has many optional parameters, but the User structure most likely requires majority of its properties to create a valid object. So, you're moving compile time checks to run time checks. You could say that you have to check if an email or a phone number is in valid format either way - ok, but then I still think it's not a responsibility of the createUser function. A dedicated Email value object that encapsulates the validation logic in a something like a factory function would be a better fit.

    • @kantancoding
      @kantancoding  20 วันที่ผ่านมา

      I disagree. I think that the builder pattern shines when creating complex objects with many fields, even if there aren’t so many optional fields. Although, the benefits of using the pattern do increase if there are optional fields, that doesn’t negate the benefits in the cases where there aren’t optional fields.
      Actually, your argument about a dedicated Email object that encapsulates validation is in support of the use of a builder in this case. Not against it.
      That’s because in many cases, when creating an object with lots of fields like the user object, there is a series of steps like assembling parts and performing validations. A builder allows us to handle these steps at different stages prior to calling build().
      This is especially useful when we are creating immutable objects.

  • @Linuxdirk
    @Linuxdirk หลายเดือนก่อน

    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.

    • @kantancoding
      @kantancoding  หลายเดือนก่อน

      @@Linuxdirk 😂 what?

  • @champx5
    @champx5 หลายเดือนก่อน

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

    • @kantancoding
      @kantancoding  หลายเดือนก่อน

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

    • @champx5
      @champx5 หลายเดือนก่อน

      @@kantancoding Alright! I shall have a look.

    • @champx5
      @champx5 หลายเดือนก่อน

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

  • @JeffersonPires90
    @JeffersonPires90 หลายเดือนก่อน

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

  • @vrmeup
    @vrmeup หลายเดือนก่อน

    Great advice, thanks 😃

    • @kantancoding
      @kantancoding  หลายเดือนก่อน

      Glad it was helpful!

  • @skelaw
    @skelaw หลายเดือนก่อน

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

    • @kantancoding
      @kantancoding  หลายเดือนก่อน

      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.

  • @tobeqz7065
    @tobeqz7065 หลายเดือนก่อน

    Clicked on the video just because i knew the comments would be spicy lol

    • @kantancoding
      @kantancoding  หลายเดือนก่อน

      😂you’ve come to the right place

  • @ФедорУсов-м9ш
    @ФедорУсов-м9ш หลายเดือนก่อน

    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 หลายเดือนก่อน

      You'll return the object at Every call lol

    • @kantancoding
      @kantancoding  หลายเดือนก่อน +1

      Not really sure what the question is here 😂

    • @kevintanudjaja7597
      @kevintanudjaja7597 หลายเดือนก่อน +1

      It's called fluent interface, or method chaining

    • @DaKeypunchAr
      @DaKeypunchAr หลายเดือนก่อน

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

  • @asagiai4965
    @asagiai4965 หลายเดือนก่อน

    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.

  • @ungrim97
    @ungrim97 16 วันที่ผ่านมา

    I am not ensure constructing a User struct to....construct a user object is great coding practice.

  • @TheScottShepard
    @TheScottShepard 13 วันที่ผ่านมา

    Spot on!

  • @sealsharp
    @sealsharp หลายเดือนก่อน +42

    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  หลายเดือนก่อน +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 หลายเดือนก่อน +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 หลายเดือนก่อน

      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 หลายเดือนก่อน

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

  • @saiuan4562
    @saiuan4562 หลายเดือนก่อน +1

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

    • @kantancoding
      @kantancoding  หลายเดือนก่อน

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

  • @Rand0081
    @Rand0081 หลายเดือนก่อน

    The first rule is already thousands of light years away from the grasp of most developers. We are doomed.

  • @LBCreateSpace
    @LBCreateSpace หลายเดือนก่อน

    Great advice Ty!

  • @duythanh90
    @duythanh90 23 วันที่ผ่านมา

    Nowaday, just write your code then use gpt to enhance that

    • @kantancoding
      @kantancoding  22 วันที่ผ่านมา

      Better off asking a 6th grader…

  • @Kokurorokuko
    @Kokurorokuko หลายเดือนก่อน

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

    • @kantancoding
      @kantancoding  หลายเดือนก่อน

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

  • @MiReiGi1984
    @MiReiGi1984 22 วันที่ผ่านมา

    Rather than a builder or even a struct to hold a set of values, instead create types for each domain concept to get rid of primitive-type-obsession.

    • @kantancoding
      @kantancoding  20 วันที่ผ่านมา

      I see your point but it doesn’t really solve the problem. For example if you have an Email type, createUser could take in fields primaryEmail and recoveryEmail both of type Email. They could still accidentally be swapped. With the builder you need to be explicit. setPrimaryEmail/setRecoveryEmail

    • @MiReiGi1984
      @MiReiGi1984 19 วันที่ผ่านมา

      @@kantancoding For such cases, yes, completely agree. Though even then I will still recommend domain types over primitives to be used with the builder. That way a PrimaryEmail or RecoveryEmail field will still hold a valid Email value, and not e.g. a street address.

  • @mumcarpet109
    @mumcarpet109 หลายเดือนก่อน +1

    Amazing 🎉

    • @kantancoding
      @kantancoding  หลายเดือนก่อน

      Thanks for watching!

  • @shanewolff94
    @shanewolff94 หลายเดือนก่อน

    What is the font used in the video?

    • @kantancoding
      @kantancoding  หลายเดือนก่อน +1

      Agave nerd font usually

  • @atabac
    @atabac หลายเดือนก่อน

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

  • @Vlad1998996
    @Vlad1998996 หลายเดือนก่อน

    these are very good videos :)

    • @kantancoding
      @kantancoding  หลายเดือนก่อน

      Glad you like them! Thanks for watching!

  • @akam9919
    @akam9919 หลายเดือนก่อน +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 หลายเดือนก่อน +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 หลายเดือนก่อน

      These posts are good advice.

    • @leerothman2715
      @leerothman2715 หลายเดือนก่อน

      @@alexaneals8194That just sounds like putting the requirements as comments in the code to me? We have better tools to capture this data.

    • @alexaneals8194
      @alexaneals8194 29 วันที่ผ่านมา

      @@leerothman2715 The problem is when the requirements are not kept with the code then bugs creep in with each release. Devs are not going to go looking through all of the requirements docs every time they change the code nor will they look at the commit statements in git or any other code repository. In reality the only time anyone looks at those statements is after everyone's hair has been set on fire with a sev 1 or 2 bug.

    • @leerothman2715
      @leerothman2715 29 วันที่ผ่านมา

      @@alexaneals8194 Well that might be your reality, but it certainly isn’t mine. Writing & reading comments isn’t going to stop bugs, automated testing will do a much better job (especially if you practice TDD). Those tests will also let all developers know why the functionality is there. If comments are so important then why do IDE’s grey them out by default, they deliberately make them fade into the background for a reason. The application requirements are not just for developers they are for the whole team to discuss along with the stakeholders, how do you do that if is distributed all over many code files?

  • @MrMassaraksh
    @MrMassaraksh 16 วันที่ผ่านมา

    Read code, not comments. That’s all

  • @KlausBayer390
    @KlausBayer390 หลายเดือนก่อน

    Which programming language is this? go?

  • @cryptonative
    @cryptonative หลายเดือนก่อน +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и หลายเดือนก่อน

      What do you mean by lsp?

    • @romanpolishchuk4517
      @romanpolishchuk4517 หลายเดือนก่อน

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

    • @cryptonative
      @cryptonative หลายเดือนก่อน +2

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

    • @МаксимГорюнов-м7и
      @МаксимГорюнов-м7и หลายเดือนก่อน

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

    • @suibora
      @suibora หลายเดือนก่อน

      @@МаксимГорюнов-м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

  • @igboman2860
    @igboman2860 หลายเดือนก่อน

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

    • @kantancoding
      @kantancoding  หลายเดือนก่อน

      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.

  • @lashlarue7924
    @lashlarue7924 หลายเดือนก่อน

    I don't really agree that code needs to be self-documented. If you have to comment it in longhand English to reduce cognitive load then you should have just written it more clearly from the outset.

  • @JProgrammingTech
    @JProgrammingTech หลายเดือนก่อน +1

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

    • @kantancoding
      @kantancoding  หลายเดือนก่อน +1

      Have you tried manim?

  • @StephanHoyer
    @StephanHoyer 20 วันที่ผ่านมา

    example of rule two is violating first rule, priceThreshold is not a good name. higherTaxPriceThreshold would be better.

    • @kantancoding
      @kantancoding  18 วันที่ผ่านมา +1

      Imo the “higher tax” part is redundant. Especially when you look at the whole statement, it’s already clear that the threshold being exceeded results in higher tax.

    • @StephanHoyer
      @StephanHoyer 18 วันที่ผ่านมา

      @kantancoding surely depends on what other constants you define in that file. If only this one I'm fine

  • @gariannobinger9933
    @gariannobinger9933 หลายเดือนก่อน +16

    "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

      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 หลายเดือนก่อน +7

      @@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  หลายเดือนก่อน +1

      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”

    • @FINALLYQQQQAVAILABLE
      @FINALLYQQQQAVAILABLE หลายเดือนก่อน

      Commenting and documenting are two separate things. Documenting modules, classes, methods, functions is absolutely a good way to provide information of what a module, a class, a method or a function is supposed to do. Most modern languages offer tools to write proper API documentation right in the code.
      Commenting lines is seldom helpful IMHO. I use to line comments only to explain unconventional bits of code that can't be cleaned up for some good reason. The reason goes into the comment.
      Call me a bad developer, but the only way I'm going to "update" a redundant line comment is to remove it altogether.

  • @AlfredLotsu
    @AlfredLotsu หลายเดือนก่อน

    the devops playlist is gone

    • @kantancoding
      @kantancoding  หลายเดือนก่อน

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

  • @el_niño_maka
    @el_niño_maka หลายเดือนก่อน +1

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

  • @coder_one
    @coder_one หลายเดือนก่อน +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 หลายเดือนก่อน +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 หลายเดือนก่อน

    🙌🏽🙌🏽❣️

  • @lucemiserlohn
    @lucemiserlohn หลายเดือนก่อน +4

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

  • @user-tk2jy8xr8b
    @user-tk2jy8xr8b หลายเดือนก่อน +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_ หลายเดือนก่อน +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и หลายเดือนก่อน

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

  • @madbanana22
    @madbanana22 หลายเดือนก่อน

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

  • @djteejay87
    @djteejay87 หลายเดือนก่อน

    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  หลายเดือนก่อน +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 หลายเดือนก่อน

      @@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 หลายเดือนก่อน +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_ หลายเดือนก่อน

      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

    • @DaSquyd
      @DaSquyd หลายเดือนก่อน

      Whether the language supports named arguments or not is irrelevant. It will always be cleaner and easier to see what the values are by a params struct. Otherwise, you'd have to check in the function itself to figure out what the arguments are. It still doesn't solve the problem of accidentally switching arguments around either.
      Regardless, if you find your function is taking in enough arguments to push it to the next line... you might want to reevaluate what it is you’re even doing...

  • @EvgenRymar
    @EvgenRymar 28 วันที่ผ่านมา

    why code in this language a so ugly?