Why boolean arguments should be avoided - Robert C. Martin (Uncle Bob)

  Рет қаралды 221,563

Dev Tools Made Simple

Dev Tools Made Simple

Күн бұрын

#cleancode #unclebob #softwaredevelopment #softwaredevelopmenttips #softwareengineering
In this video, Robert C. Martin A.K.A speaks on the types of arguments developers should avoid. He brings to mind reasons why some types of arguments can and often do make the code more difficult to understand, and potential ways to improve.
What do you think?
Source: • Clean Code - Uncle Bob...

Пікірлер: 559
@matheusaugustodasilvasanto3171
@matheusaugustodasilvasanto3171 4 ай бұрын
About the boolean arguments, other comments seem to be focusing too much on the control flow aspect of the problem ("don't you just end up making the decision somewhere else?"), and not enough on the software design aspects (except myPrzeslaw, he seems to get it). Here's my take. IN TERMS OF SOFTWARE DESIGN, I can see the following benefits to what Robert C. Martin is suggesting. Extracting distinct branches into separate functions. f(..., bool b) { if (b) { f_true(...) } else { f_false(...) } } Symbolic names. "Never" write function names like this. Reusability. You may want to re-use the behavior for a specific branch elsewhere, in a place where perhaps the other condition cannot occur. Extract the function allows for code reuse, without tangling the caller with an unnecessary dependency for both cases. Configurability. "Bubbling up" the interesting decisions for a program is an excellent way to make code easier to understand, maintain and extend. Centralizing a point where program behavior is decided, and segregating it from where the actual actions occur, is a general principle which brings many benefits. See also CQRS, Functional Core + Imperative Shell, Strategy Pattern, ... Using Enums (not a recommendation by Martin in this video, but a general pattern to avoid boolean arguments) Understandability. As he said, boolean arguments can be very cryptic reading from the outside. createEmployee("John", 27, true) is fundamentally less understandable than createEmployee("John", 27, Status.EMPLOYED); this is mitigated in languages like Python with keyword arguments. create_employee('John', age=27, is_employed=True) Extensibility. Perhaps in the future the code might have to deal with more than two cases. Booleans are an inherently restrict data type, with only two valid states (discounting unfortunate languages with null-like values for it). They are perfect for some situations, but not for others. For a more flexible design, Enums are the way. Extra point for backward compatibility when adding Enum states. Some type systems offer ever better extensibility and safety (Rust comes to mind). General software engineering disclaimers: * details for a specific situation matter; do not presume everything here is applicable to all cases * there are still downsides to the suggestions here presented; everything is a trade-off
@MrHaggyy
@MrHaggyy 2 ай бұрын
Was about to say the same. A bool is the easiest type of state and is quite useful in describing the state of a system. In Industrial applications, you have a chain of checks, usually normed, like MainPower = true, FailSafe = false, Input1 = ?, Overheat = false, Enable = true, etc. While some get linked in enums, like idle, start, running, and stop could replace an enable For others it doesn't make sense. A fuse for example is either blown or not. In your code, there are a few ways to handle this. Switch case: This type of data is usually aligned, so you can treat it as one variable and program the right behavior for each combination. Code like this reads similar to technical documentation. If-Tree: This is useful if there is a hierarchy, or behavior is independent from the rest of the data. When there is no MainPower or someone pulled an emergency stop I don't need, any further information to stop the system. (You will need it to do it save). But for overheating for example, while it might be interesting to know what causes heat or how hot it is, there is only so much your system can do. In a car for example the fan behind the intercooler can either run or not, so a bool is all you can do. This is very readable if you think of root-cause patterns. Queue: If the system gets really complex, you might divide it into subsystems sharing one state of the system. But at this point, you are passing structs and returning a return type. I really like custom types. John = either Employed or Unemployed or Fan = either On or OFF is less complex than translating it to true and false. And this can get tricky. While overheating and fan = true means it is overheating and the fan is running, Main and EmergencySwitches are active high. This means while there is power and NO emergency the signal gets power and the bit is 1 = true. If any machine has an emergency it pulls the entire signal down so emergency = 0/false means there is an Emergency. If you rename those states it's less complex.
@pikachufan25
@pikachufan25 2 ай бұрын
i heard this once - Readable code is Less Performant but easier to Debug Less Readable Code is More Performant but Harder to Debug (Due to Using The Most Efficient Possible Answear instead of Making it the Most Easiest to Edit...)
@ShorlanTanzo
@ShorlanTanzo 2 ай бұрын
This must be what it's like for normal people to try to read code.. Read a line, freak out.. read a line, freak out... it sounds absolutely exhausting
@armelpeel
@armelpeel Ай бұрын
I dont think it is cleaner, nor is it more clever, to write two separate nearly identical functions simply because you have invented an arbitrary rule about passing booleans to functions. If this thing happens, process like this. Otherwise process like that. Writing two separate functions because you dont want to pass a boolean is not the solution. Not nearly.
@JumbaJumby
@JumbaJumby Ай бұрын
@@armelpeel You are missing the point. If the functions are small and simple enough, you can simply accept two functions, or replace the boolean argument with a type that is more descriptive or extensible in the future. If the function is larger and yet contains some form of boolean-based branching, then there should be sections of that function that can be separated into their own functions. So you don't end up with two almost identical functions. You end up with one function that contains the shared code and the small differences are performed outside that function. By keeping the work of each function simple and focused, you can then reliably create a hierarchy of function calls that will likely not require refactoring due to being so focused. This doesn't matter for one-off one-and-done projects, but in anything that requires longterm maintenance it's a minor win that builds up over time.
@user-sl6gn1ss8p
@user-sl6gn1ss8p 2 ай бұрын
You know, it's always Uncle Bob asking me to avoid others - Booleans never asked me yo avoid Uncle Bob, for example. I think I'm starting to see who is the toxic one here.
@TheScottShepard
@TheScottShepard 2 ай бұрын
I identify as Boolean and it’s mean.
@ninobach7456
@ninobach7456 2 ай бұрын
True ​@@TheScottShepard
@mepipe7705
@mepipe7705 2 ай бұрын
You must be a strong character to stand that toxicity
@redpepper74
@redpepper74 Ай бұрын
@@TheScottShepardnot false
@kayakMike1000
@kayakMike1000 Ай бұрын
Well, that's rude.
@jbird4478
@jbird4478 2 ай бұрын
After years of programming I've come to the conclusion that all programming rules can be summarized as "you shouldn't do things except when you should".
@emblink27
@emblink27 2 ай бұрын
😂 Nice
@Murukku47
@Murukku47 Ай бұрын
One should remain especially vigilant around the bad ideas that are known to be sometimes necessary.
@elatedbento
@elatedbento Ай бұрын
All life can be summarized to "you shouldn't do things except when you should".
@5cover
@5cover Ай бұрын
Yep, it's a big mess that nobody understand. Kinda like math's ugly child.
@ivantatarchuk697
@ivantatarchuk697 2 ай бұрын
Don't write code! The best code is that you have never written.
@programmer1356
@programmer1356 2 ай бұрын
The best code is code that _you_ haven't written [hahahah, sorry, I had to]
@nyarlathotep7204
@nyarlathotep7204 2 ай бұрын
TRUE
@user-sl6gn1ss8p
@user-sl6gn1ss8p 2 ай бұрын
@@nyarlathotep7204 did you just use a boolean?
@vitobrx
@vitobrx 2 ай бұрын
Your sentence returns a True
@lpi3
@lpi3 2 ай бұрын
​​@@vitobrxbut there is no return operator. It looks like it returns void.
@MrKrtek00
@MrKrtek00 2 ай бұрын
can we have a little more dramatic music?
@louen8413
@louen8413 2 ай бұрын
I was kinda disappointed, was waiting for the swordfight to start at any moment...
@heyhoe168
@heyhoe168 2 ай бұрын
@@louen8413 is this why you descended to a comment section?
@smort123
@smort123 2 ай бұрын
A bit more noise maybe?
@ekkehardehrenstein180
@ekkehardehrenstein180 2 ай бұрын
I really felt UBs normative nature required some reinforcing nature. I never felt quite coerced and dictated enough, so by now, I don't even dare to reconsider any more.
@mepipe7705
@mepipe7705 2 ай бұрын
​@@smort123a bit is a boolean and thus bad as an argument, as I understood
@byrey3
@byrey3 2 ай бұрын
Of course, why would I want to have 1 function with 3 booleans along, when I could have 8 functions!!! And the moment I wanted to change 1 aspect of it, now I would change it 8 times on the infinitely long library
@oli_dev
@oli_dev 2 ай бұрын
If you need to change something 8 times in this scenario, you probably arent using helper-functions when you should
@byrey3
@byrey3 2 ай бұрын
@oli_dev So I have to replace my function with 8 different functions for each case of the booleans, and also the functions shouls be entirely done with helper functions. The insanity keeps getting better, just as I like
@oli_dev
@oli_dev 2 ай бұрын
In practice, what I would do in this scenario is use 1 function, but pass keyword-arguments, or create some sort of struct on the stack that contains the booleans. Something like: myFunc({ foo: true, bar: false, tux: true }) This way, you get the readibility benefits, AND the benefit of only having 1 function. (My previous point still stands tho, if you had 8 functions, and you were duplicating code across each, then you are probably not using helper functions when you should)
@byrey3
@byrey3 2 ай бұрын
@oli_dev And finally you realice that this man is out of his mind trying to be controversial with this nonsense
@JacobNax
@JacobNax 2 ай бұрын
apply responsibility principles and you dont have to add 3 bools in a function in the first place. You wont get this now but one day you will
@adambickford8720
@adambickford8720 2 ай бұрын
People are missing the point, of *course* you're just moving the boolean, that's the point! There's an old saying "push 'if' up and 'for' down". Your function should either be doing work, or coordinating work, not both. Code that only coordinates other code is usually higher level and more 'volatile' as it changes w/the business. The lower-level code should be as 'context free' as possible as context is the problem the calling code is solving.
@somestrangescotsman
@somestrangescotsman 2 ай бұрын
I've seen enough code to know that spreading around use cases is dangerous. I mean "determine_nav_solution" can be as simple as a few matrix multiplications, but it has a need for a bunch of booleans - I can think of at least 8 possibilities. Nobody sane would want 256 different functions, with names describing each bool.
@lpi3
@lpi3 2 ай бұрын
Other words function should have only a bunch of assignments, one loop, one switch or one if else operator.
@ilonachan
@ilonachan 2 ай бұрын
but… coordinating work IS work. This principle can literally not work anywhere unless your "coordination" is completely trivial.
@adambickford8720
@adambickford8720 2 ай бұрын
@@ilonachan You have much more learning to do
@ilonachan
@ilonachan 2 ай бұрын
@@adambickford8720 can only be the response of someone who doesn't work with a real codebase
@yrds96
@yrds96 2 ай бұрын
- Raises a problem - Doesn't come up with a solution. - Leaves Classic Uncle Bob
@alexcarrasquillo1
@alexcarrasquillo1 2 ай бұрын
Wait what? Didn't he just say to use 2 functions?
@preemtimhaxha5309
@preemtimhaxha5309 2 ай бұрын
@@alexcarrasquillo1you’re still gonna pass that boolean to the other function no?
@alexcarrasquillo1
@alexcarrasquillo1 2 ай бұрын
@preemtimhaxha5309 No! The point is to split the load and add clarity. Instead of having chunky logic in one function based on the state of the book that's passed in, you decide which of two functions to call from the call site. You still need to use the boolean at the call site, but it has a clear intent. Call function A because the bool is true or call function B.
@Chris-jm2gx
@Chris-jm2gx 2 ай бұрын
@@preemtimhaxha5309 are you high? dafuq do you mean you will still pass the bolean? If you have toggleSomething(bool), Uncle Bob is suggesting to instead write turnOnSomething() and turnOffSomething(). No need to pass anything if the original only needs a boolean.
@WalderFrey
@WalderFrey 2 ай бұрын
​@@preemtimhaxha5309No
@MsBukke
@MsBukke 2 ай бұрын
The thing i like about boolean parameters is that some languages allow optional values that have a default value and in that case you have a default behavior and an edge case
@alexchexes
@alexchexes 2 ай бұрын
Yeah, true, but that also becomes a refactor hell. When you have thousands of function calls where almost all of them are called without arguments, you need to check all 1,000 to find if there’s that one edge case where it’s called with an argument. Project-wide search helps, but why complicate things when they could be easy? A separate function for the edge case.
@makeavoy
@makeavoy 2 ай бұрын
​@@alexchexes if the control flow is too saturated with that optional Boolean you're basically guaranteed to need to make it a private function that's called by two new public functions without that param. It feels like too much abstraction to me unless you're writing some library or API. Also that optional param is great for passing a debug flag for unit tests.
@TheViettan28
@TheViettan28 Ай бұрын
I hate and like it at the same time, the default value is hell in a big project. Those value should be passed explicitly.
@gabiold
@gabiold Ай бұрын
When you statically calls the function, especially just one side all the time, that's EXACTLY the case which badly needs two functions instead! You are evaluating IFs in every call while you KNEW compile time which leg will be executed.
@MTAG
@MTAG 2 ай бұрын
Just write the code that works Boolean parameters or not, single function function or not. Don't worry about that until it becomes a problem, chances are it never will. It is guaranteed 100% you will refactor your code anyway, for some other reason. Premature optimization and overdesigned patterns are a waste of your time.
@adamrussell658
@adamrussell658 2 ай бұрын
Trouble is that you probably wont ever see the problem. Its usually only an issue after you are gone and the next guy is asked to work on your code. Then he will be like "I dont see why this problem code is even in there. Do I dare simplify it or will that cause issues Im not aware of"?
@MTAG
@MTAG 2 ай бұрын
@@adamrussell658 If it wasn't an issue while you were there why is it suddenly an issue with the new guy? Maybe it's the new guy issue?
@mariusg8824
@mariusg8824 2 ай бұрын
I hate to agree with you, but I do. So much goldplating done on the wrong end.
@NerdyStarProductions
@NerdyStarProductions 2 ай бұрын
I think you took the wrong message away from the video. The point of avoiding bool args unless you have good reason to use them isn't about optimizing or anything like that. It's literally just a slightly more advanced/manual linting thing you can do to make functions easier for the next person to understand. Nobody's going to die if you have bool control flow args, in the same way that nobody will die if you use snake case for your JavaScript variables, or if you cram multiple lines of code into 1 single line. But it can be easier for people's brains to follow your code if you follow some of these simple ideas. You might then ask how does a bool control flow arg break convention? Well it doesn't really break convention like the other examples I mentioned would, but it's more just a convention to be aware of for making code easier to read by other people. When people see a function called "createPerson", the default assumption is that this function will just simply create a "person" resource whenever called. Control flow args can lead to this expectation being broken. If you instead just write the conditional branches explicitly and use separate functions, it can be easier to read and understand what actions are taken under which circumstance. But again, this is not a hard and fast rule, as there are definitely lots of scenarios where a bool arg makes code easier to understand. It's more just a "when in doubt, do X" type of rule.
@MTAG
@MTAG 2 ай бұрын
@@NerdyStarProductions I think you missed my point. The problem with premature optimization is in the word premature. Everything premature is bad. Including getting rid of Booleans for mythical "readability" as you or someone else "sees" it. This causes you to overdesign something to avoid imaginary problems in the future. Tell me which code is harder to refactor: - Dirty Boolean ridden piece of shit with no architecture - Crystal clean but WRONG architecture
@sealsharp
@sealsharp 2 ай бұрын
Yes, the if(...) inside a function can be avoided by having two functions. Which leads to the follow up question: Will there be an if(...) outside of the functions? Because if yes, you would just move the additional code to some other place. It would not reduce the complexity or the amount of code. It's just someone else's problem. If the boolean argument is usually a constant, make it two functions. If the boolean argument is usually not constant, keep it as a parameter.
@ber2996
@ber2996 2 ай бұрын
well there would be an if outside for sure to know which function to call lol reverse = true; if(reverse){ return reverseTrue(); }else{ return reverseFalse(); }
@rouenyu
@rouenyu 2 ай бұрын
Exactly what I think
@nnnnnNicol
@nnnnnNicol Ай бұрын
Just write two programs
@Waldemar_la_Tendresse
@Waldemar_la_Tendresse Ай бұрын
Just write many simple programs and use a pipe! 😁
@THE4ECHOK
@THE4ECHOK Ай бұрын
I see two ifs in your comment. You should've write two comments
@VictorMartins239
@VictorMartins239 2 ай бұрын
so the reason is because he doesn't like it
@jameslay6505
@jameslay6505 2 ай бұрын
the reason is because it is a smell that your function is actually hiding several other functions within it
@ObesityStupidity
@ObesityStupidity 2 ай бұрын
@@jameslay6505 aaaand? What is the problem?
@MichaelBarry-gz9xl
@MichaelBarry-gz9xl Ай бұрын
Try it, refactor your code to bubble up the decisions and seperate then from the actions. When you see how readable the code is you'll never go back
@jakobpederpettersen2179
@jakobpederpettersen2179 2 ай бұрын
Dropping the boolian argument and splitting the function in two is a good idea if the called function branches right away. However, in many cases the function follows mostly the same logic (and code) for the two values, the boolian option is there for a slight variation. Splitting such a function into two would double the amount of code and make it less maintainable. Alternatively you could try to use the same code for two different functions by applying metaprogramming, but such solutions can quickly become ugly, especially when done with C macros. From a performance perspective, I have experienced that the compiler often will optimize out the boolean variable and effectively call two different functions depending on the value. This is very useful when the branch is written within a tight loop. Therefore: Strive to write the code for the humans, and let the compiler help write the code for the machine.
@maskedredstonerproz
@maskedredstonerproz 2 ай бұрын
I'm no uncle bob, or any expert on his level, but what I've gotten from things like this, don't pass booleans, don't use repositories/use cases, do this, do that, is that it depends where you use it, it's not a strict, you HAVE to do this type of deal, in your example sir, what I would do, is either not abide by this recommendation, and just pass the boolean, or the code that the two functions have in common, I'd just extract into a separate function, that I call from the two variant functions
@brainmaxxing1
@brainmaxxing1 Ай бұрын
Eh, I mean your example could be fixed by refactoring all the similar code into a common function, then when branching call two smaller functions that implement the different functionality
@АлексейПешков-г8ь
@АлексейПешков-г8ь Ай бұрын
1) In many situations the one function is a slight variation of another simpler function and can be written using composition of simple function with some prolog and/or epilog. 2) In another often situation boolean can later expand into 3rd case or another orthogonal boolean. In that situation enums (or bit enums that can be combined with binary OR into one parameter) are the best choice from the very beginning.
@Zocress
@Zocress 9 ай бұрын
My function names after this talk be like: copy_files_but_do_not_overwrite_older_files_but_do_override_if_file_is_smaller EDIT: Guys, it's a fucking joke. The people in the replies trying to explain how this is a bad practice are why programmers have a bad rep for our social skills. Jesus Christ.
@GiovanniCamellini
@GiovanniCamellini 2 ай бұрын
😂
@abiofficial-ws7pn
@abiofficial-ws7pn 2 ай бұрын
Actually I do that too. Good to know that I'm not the only one on the planet.
@saryakan
@saryakan 2 ай бұрын
When you have complex behavior like that, it's probably better to pass it as an enum instead of splitting it into many different functions.
@GiovanniCamellini
@GiovanniCamellini 2 ай бұрын
@@saryakan For some reasons this actually reminds the tax-loss harvesting structure that some trackers apply on portfolios with several different cryptocurrencies in it
@psychic8872
@psychic8872 2 ай бұрын
You probably need to inject a function of when to overwrite instead of booleans
@abderrahmanemya6602
@abderrahmanemya6602 2 ай бұрын
i feel bad for all the people who had their time wasted for attending this. unless it was advertised as a pure comedy show
@robertmainville4881
@robertmainville4881 2 ай бұрын
Still trying to understand the argument against using a boolean in a function. 🤔
@Jabberwockybird
@Jabberwockybird 2 ай бұрын
It's not so much the boolean. I've seen the problem happen with strings/enums. It's where you have two separate bits of code that accidentally got put in the same function and the caller has to pass in a "hey run this peice of code" flag. And the different paths are so separate that they didn't need to be in the same function in the first place. I see that happen a lot becuase people think they are being DRY and they make a bad abstraction
@shashankadas5227
@shashankadas5227 Ай бұрын
@@Jabberwockybirdi agree. I work with these code regularly, but this has nothing to do with what martin states. If you have a function which ,unironically, does 2 functions, there are much bigger problems in your code base. And neither is having a bs piece of code like doXWhenY. It makes sense only when the two parts have no correlation to each other, like what i stated before. But usually, they are related piece of work, with a common functionality branched out because of a conditional. A much better way for abstracted away code is use enums, it helps a lot stating Enum.Value instead of true. Ofcourse there are some restrictions but it doesnt limit you to 2 absolute states, which will break in the future when requirements start to dilute in the future. For example: ReturnPlayerHistoryIfMale and ….Female, i would never in my life accept that code. This highlights the other point too, if 10 years back you used true or false,the entire thing needs to be refactored. Use an enum ReturnPlayerHistory(long playerId, Gender gender) . Makes it much cleaner
@giornikitop5373
@giornikitop5373 Ай бұрын
@@shashankadas5227 good point, bad example. there were only 2 and will ever be 2 genders, so bool is perfectly fine in this. no need to use an enum.😎
@TomZimmerman-s1q
@TomZimmerman-s1q 2 ай бұрын
This is such a non problem.
@lpi3
@lpi3 2 ай бұрын
It is problem when you have 6000 lines function
@jeremykiel6709
@jeremykiel6709 2 ай бұрын
@@lpi3 well maybe the solution is to not have a single 6000 line function in the first place
@lpi3
@lpi3 2 ай бұрын
@@jeremykiel6709 of course. It was not me, who wrote those lines.
@Flylikea
@Flylikea 2 ай бұрын
Depends... this if is_outlier: handle_outlier(data) is definitely not the same as this if data.quality == "outlier": handle_outlier(data)
@Mathhead2000
@Mathhead2000 Ай бұрын
It's a non-problem because people have adapted better choosing standards over the years. Libraries from the 90's and earlier do stuff like this a lot and I agree that it's a little rude. Although, it's one of those insidious bad design patterns where it doesn't feel that bad so maybe you just keep doing it. But in maybe cases, just having two functions is cleaner and more intuitive. I'm glad this isn't a problem anymore.
@rmcgraw7943
@rmcgraw7943 3 ай бұрын
I’d say Uncle Bob needs to spend a few more years writing code before he starts advocating universal design patterns. There are use cases when both bools as parameters and output parameters are quite appropriate and the best solution. TryParse, for one instance, is a perfect usage of out parameters.
@DeclanMBrennan
@DeclanMBrennan 3 ай бұрын
Depending on the language, returning an optional or a tuple might be more readable. Alternatively, some languages require you to decorate the argument with "out" at call time which at least makes it obvious which arguments might be changed by your function call.
@xucongzhan9151
@xucongzhan9151 2 ай бұрын
Idk man... I have been tortured by bool args enough to agree with Uncle Bob. In over 90% of the cases they are just bad design.
@Jabberwockybird
@Jabberwockybird 2 ай бұрын
Bob has been programming while you were in diapers. And he specifically started out with a disclaimer that you don't always avoid bools. Stop avoiding good advice because you get caught up in whataboutism
@elijahshadbolt7334
@elijahshadbolt7334 2 ай бұрын
TryParse is a symptom of the language lacking a good way of unwrapping an Optional (Some/None) type. Just return a nullable and you wouldn't need an out parameter.
@scheimong
@scheimong 2 ай бұрын
​@@elijahshadbolt7334Rust mentioned?
@SavagioTs
@SavagioTs 2 ай бұрын
Finally, a standup comedian I can relate to!
@DannoHung
@DannoHung 2 ай бұрын
What Bob's actually arguing against is allowing default named values to be filled by unnamed positional parameters. In the code example provided, the issue becomes a complete-non issue if the default is named in the call-site: printName('Olga', 'Puchmajerova') printName('Olga', 'Puchmajerova', reverse=True) Parameterizing behavioral changes is a far more compositionally friendly approach than creating parallel implementations as well. Bob has mischaracterized a language design issue as a coding hygiene issue. Similarly, output parameters are a similar symptom in *most* cases of not having one of tuples or variants in the language.
@ObesityStupidity
@ObesityStupidity 2 ай бұрын
I actively use Python in my projects and already forgot that this was an issue in other languages. Keyword arguments are very useful
@aheendwhz1
@aheendwhz1 Ай бұрын
I think it makes sense to pay attention when using boolean arguments, because there might be a more elegant/better solution - but in a lot of cases, there isn't, and boolean parameters are fine. Sometimes, passing a strategy/callback (however you wanna call it) instead of a boolean can add a lot of flexibility with minimum overhead. Sometimes, splitting your function down in a few "do" functions and one "coordinate" function makes testing easier and is going to come in handy when you restrucutre your code, add more functionality or change existing one. Especially when you work on library code, it can help getting the desired behaviour with out requiring backwards-incompatible changes upstream. But there are cases where splitting the code is bullshit, especially if the "do" code is just very small and minor. In general, most code design nitpicking is mainly useful for library code, where you design APIs that you don't want to break in the future and therefore try to be as flexible as possible.
@zionklinger2264
@zionklinger2264 2 ай бұрын
Boolean arguments have never confused me after I started using inline hints (Microsoft calls it code lens I think). With it turned on the parameter names are displayed (in greyed out not distracting text) right next to the argument. So instead of a random false, it says "is_clean_code_good_code: false" literally a non issue
@FlowerBoyWorld
@FlowerBoyWorld 2 ай бұрын
wtf booleans are literally the easiest things to read
@SmallSpoonBrigade
@SmallSpoonBrigade 2 ай бұрын
Not if the value is being set by some bit of code that's several pages away or is in a completely different file it isn't.
@lukkkasz323
@lukkkasz323 2 ай бұрын
​@@SmallSpoonBrigadebut why is that relevant, when reading it you care about all cases true and false, and so state is irrelevant, and when debuging with any competent editor you already know the state, so the bool reads like a part of the function name.
@gabiold
@gabiold Ай бұрын
setTheme(true) is easy to read, just what it does, is the big question... setDarkTheme(true), is a bit better, but still begs the question, what will be the theme if it is not dark? Light? Or system-default? enum Theme { Light, Dark }; setTheme(Theme.Dark) is better and extendable. However, for pure unambiguosly two-state logic, it is fine, eg. setEnabled(true) is quite self-explanatory. Using the above concept for this would even make it worse, eg. setEnableDisableState(State.Enabled) looks ridiculous.
@MrMoralesOrlando
@MrMoralesOrlando 2 ай бұрын
Today him say this tomorrow "Avoid to many functions" after that " make your code shorter" after that "express more your code, the problem with those guys is that they have so many things in their head that they ended with a" mess of good ideas " the best code is the code that works properly and do it simple !
@TheNewton
@TheNewton 2 ай бұрын
"the best code is the code that works properly and do it simple !" So simple this will idea revolutionize the software industry. Why didn't anyone ever think of this before it's so simple! Surely you've solved every businesses software development problems you'll be a trillionaire.
@leokiller123able
@leokiller123able 2 ай бұрын
If your entire function is a if statement around a boolean argument, then yes, it makes sense to remove that boolean argument, but there are plenty other places where boolean arguments totally make sense (eg. a verbose argument)
@sergioengineer
@sergioengineer 2 ай бұрын
Just found out about this channel and I have to say that I wish I didn't. The opinions exposed here are too shallow; lacking the necessary examples to defend your points. They don't seem to be backed by a lot of experience to be honest.
@Jabberwockybird
@Jabberwockybird 2 ай бұрын
I have experience and I agree with the bool argument. Bob has experience, but I think he presented the problem wrong. An example would have helped.
@mannyc6649
@mannyc6649 2 ай бұрын
This is too broad of a rule tho. What if I have a function for which I want to make logging optional. def do_thing(inputs, logging: bool). Am I supposed to duplicate this function only to have logging done in one of the two? Am I supposed to define a length-two enum for the sole purpose of toggling some prints? What if, instead, I have a function with two branches which are known at runtime? Am I supposed to put ifs before every function call instead of just putting one in the function definition?
@nekononiaow
@nekononiaow 2 ай бұрын
Return the string to log instead. This way the caller decides whether to ignore or display it. Then they can call Log(DoThis()) or simply DoThis(), which is clearer for the reader anyway and gives them control on how to log/display it, which they would not have if that was inside the function.
@mannyc6649
@mannyc6649 2 ай бұрын
@nekononiaow logging may appear in different parts of the function and not necessarily in all paths. Also some logger libraries record the location of the current execution frame (line no. and file) so returning the string would invalidate this information
@Murukku47
@Murukku47 Ай бұрын
Hot take: don't pass in a bool, especially if it doesn't affect the function's business logic or result, especially if that bool remains unchanged for large stretches of time rather than constantly carrying some regular busywork involved in some specific logic, and especially if this is a pattern that will also repeat in other function(s) as well, moreso if needing to disable logging is only loosely or not at all related to when/how the function is called . Instead, it's time to make a global flag LOGGING: bool that enforces the desired behavior and the function can just read without passing it in as an argument. Why? Because it's dead-explicitly predictable what kind of behavior some "if LOGGING == false: enable_logging()" will invoke even if you've never seen the code or the program before, because it is simple as a structure (single value in memory), because it doesn't pollute your function arguments where logging: bool can be ambiguous on functions that return some object: it'll look like you're creating a new object with its logging disabled rather than just not logging for that function's run. An enable_logging() and disable_logging() sandwiching your function call is slightly obtuse but extremely explicit and self-explanatory. Don't do this if you never need to do this elsewhere though or if you need to switch it on and off so often that the calls to toggle it make the code harder to understand, but I find it odd that you'd hardcore some specific function to just never log, maybe making that stand out more is a good idea? I know it seems simple to just pass in a bool but it's not very intuitive to read: is it even obvious that its effect only lasts for as long as the function itself? Logging is one of the few things where globals make sense as it's expected to have identical lifetime to the entire program.
@pmkaboo2446
@pmkaboo2446 Ай бұрын
no in this example youre good, what you shouldnt do is `def do_thing(inputs, special: bool); if special do special thing; else do normal thing`
@davidwuhrer6704
@davidwuhrer6704 29 күн бұрын
Just call the logging function regardless, and let the logger worry about it. The simplest scenario is writing to stderr. Let the user or the calling script or whatever redirect it to /dev/null. Most loggers have log levels, so a boolean isn't enough anyway. The question becomes not whether to log, but how verbose the log should be. And that, too, should be up to the caller.
@HollywoodCameraWork
@HollywoodCameraWork 2 ай бұрын
That's a shite reason to not use boolean arguments. Breaking everything up into tiny functions is a composition nightmare, with a code flow that no human can understand. Our worst code is exactly like that. The really good reason is that with multiple arguments of the same type, you'll eventually mix them up. Use type aliases for everything, including booleans and integers, so that you can never mix a "recursive" with "includeDotDirectories", because the function is "search(Recursive(true), IncludeDotDirectories(false))". Our number of bugs from such mistakes has dropped to zero.
@giorgos-4515
@giorgos-4515 2 ай бұрын
Type Aliasing is a chore in most mainstream languages, F# has it greatly done
@holger_p
@holger_p 2 ай бұрын
If all the code is under your control, and the function is not virtual, at least think about it. Multiple functions is one way to solve it, your specialized boolean-like types, is another way. (Aliasing is not a well defined term, cause it works mutual in some language, making two different terms interchangable, it doesn't create a new type).
@nekononiaow
@nekononiaow 2 ай бұрын
How is it a composition nightmare? Composition is much simpler when the elements to compose do one single thing each.
@holger_p
@holger_p 2 ай бұрын
@@nekononiaow So you prefer to assemble something from 500 single pieces, rather than from 10 pieces ? Think on a shelf from IKEA. As more parts, as more you have to think on, as more you have to understand, what is good for what.
@davidwuhrer6704
@davidwuhrer6704 29 күн бұрын
​@@holger_pYou are not writing assembly code or designing a processor instruction set. You are not assembling something from hundreds of pieces. You are using abstraction. Every complex system that works is built from simple systems that work. Small functions that do one thing each, and do it well, are easy to prove. From those you can create more abstract functions, or more specialised functions. Again, simple functions, small functions that happen to rely on other functions. You are creating an interface. The interface should not change, but the details of the underlying implementation can. This is also how you should write assembly code. Create abstractions. This is also why RISC processors outperform CISC processors on every metric. In the end you don't assemble your system from hundreds of parts, you use a handful of parts. Each of those parts is made from a handful of parts, and each of those is made from a handful of parts. That way, each layer is simple and provable. This is how a programmer divides a big problem into small problems. It's a core skill for programming. Divide and conquer. That's only part of it, of course. You also want reusable parts. You want parts that can be replaced with ease. You don't want to solve the same problems over and over again. (If you do, don't write code.)
@thyssenbot
@thyssenbot 2 ай бұрын
Uncle Bob forgets that the passing bool preserves encapsulation,esp in microservices. Suppose you want to get some data and you don't want it to be cached/fetched from cache. If you don't pass bool, then you have to expose two functions.
@TheNewton
@TheNewton 2 ай бұрын
named arguments , e.g. render(data, cache = false);
@davidwuhrer6704
@davidwuhrer6704 29 күн бұрын
No, it doesn't. It's the exact opposite. You are exposing a detail of your implementation in the API. Not in your example. Your example is a parameter in the API that decides which function to call. What Bob suggests is that those two functions _should be two functions._ The idea is that you _don't pass the boolean_ to the implementation. Alternatively, you could have a separate end point or other mechanism for invalidating the cache, but I guess that for some reason you don't want that. I feel that the user agent having to know that there is a cache in the backend is already exposing too much implementation detail.
@DataPastor
@DataPastor 2 ай бұрын
So it is better to have 2 functions instead, for doing almost the same? Or if I have 2 boolean options, having 4 functions, and creating a dispatching function for the 2 booleans (a total of 5 functions)? It doesn’t add up.
@maximo666
@maximo666 2 ай бұрын
I think what he means is to write simple code in the likes of doThis(); doOtherThing(); Code should be written in a way that its pourpose is clear right at first glance. If you start checking what happens within the if and then the else and then you need to go back to double check previous stuff...then that code is hard to read
@holger_p
@holger_p 2 ай бұрын
Do the dispatch at the caller side. Especially when you pass constants arguments, literally with "true" as argument, you will notice the entire dispatch is meaningless. You would create code doing "if (true) ...". But you don't realize it, if you hide this in arguments.
@barongerhardt
@barongerhardt 2 ай бұрын
The bool thing is simple enough, but boy do I hate passing in a return. When debugging someone else's code having a value changed because it was used as a function input is so easy to miss and not understand why/where it changed.
@James-l5s7k
@James-l5s7k 2 ай бұрын
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) Good rule for normal arguments, disagree in the case of kwargs (if your language has it). Obscure options that require a something=True flag to be passed into the function. Can you imagine how awful it would be to have open functions based on the behavior you want instead of just passing a kwarg? Probably about as awful as having booleans as args!
@oli_dev
@oli_dev 2 ай бұрын
Yes, oh my gosh. I was looking for ages for this comment. I couldnt agree more
@koktszfung
@koktszfung Ай бұрын
What he wants: open(file) open_closefd(file) 😂
@meanmole3212
@meanmole3212 9 ай бұрын
Thanks, this vital insight helped me to code Quake 1 rendering engine, in fact it would have been impossible without this magnificent knowledge.
@OhhCats
@OhhCats 2 ай бұрын
with bool arguments code runs too fast
@davidwuhrer6704
@davidwuhrer6704 28 күн бұрын
Rather the opposite. Each bool represents a conditional jump, and each conditional jump in the control flow slows down the code by half.
@UberDragon
@UberDragon Ай бұрын
I feel like most developers just look for reasons to explain why their way of doing something is actually the smartest. They will go through a lot of effort to explain something in a way that frames what they're saying as an objective truth that god put out there for them to find. Don't do that. Do what suits you best and if that is endless nesting so be it. Chances are in 5 years from now everyone will hate early returns and praise nesting as a lot better, you'll then have about 5 years during which you're a coding genius, after which some other method will become the new magnum opus of coding. If you're working on already existing code, try to be in line with how the code usually does stuff to the best of your ability without hindering your progression too much. Anything beyond that I consider a waste of time, because no matter what reasons there are for something, someone else will find different reasoning on why it's bad and needs to be changed.
@victorbaxan7436
@victorbaxan7436 2 ай бұрын
Depending on who's reading the same piece of code, you'll have bored, surprised, amused, disappointed, defeated, angry etc, etc people.
@JoepKockelkorn
@JoepKockelkorn 9 ай бұрын
I love the solution. Oh wait it isn’t mentioned. That’s rude…
@GoldenBeholden
@GoldenBeholden 9 ай бұрын
He recommends putting each branch into its own function.
@Zocress
@Zocress 9 ай бұрын
@@GoldenBeholden That just moves the if statement up to wherever the function is called. It doesn't necessarily decrease if statements, it may actually just cause more to happen, because they aren't "allowed" inside the function itself.
@euunul
@euunul 9 ай бұрын
​@@GoldenBeholdenand what's the point? You'll still have to evaluate a bool and call the appropriate function. And that will happen in a function that has to take a bool as argument or evaluate a bool variable. So what's the point?
@GoldenBeholden
@GoldenBeholden 9 ай бұрын
@@euunul @Zocress A well named function makes for more semantic code, while each function can be simplified by just focusing on a single thing. I'm not saying this is always the proper solution, it's just what is suggested in this video.
@unlomtrash
@unlomtrash 9 ай бұрын
​@@GoldenBeholdenI also do this when I have more than two if-branches
@alejandroill
@alejandroill Ай бұрын
I have a genuine question about this. Say you have a function thats N lines of code, accepting a “flag” Boolean argument as input, which takes up K lines via an if statement where K
@Nina-cd2eh
@Nina-cd2eh Ай бұрын
Pretty simple. Move those N common lines into a separate function
@AutoGibbon
@AutoGibbon 2 ай бұрын
What's the battle music for? It's really annoying.
@Stratelier
@Stratelier Ай бұрын
Back when I worked with Visual Basic, I generally stopped using Booleans as parameters but for a different reason: that language provided a specific "Boolean" data type, but which for some reason allocated 2 bytes per variable. If that sounds utterly _wrong_ for a value that can be stored with just a single bit, it gets better: Due to some shenanigans/bugs resolving whether boolean _keywords_ ("and", "or", etc) were to be interpreted as logical or bitwise operations, it became clear the Boolean "data type" was just syntactic sugar for its (16-bit) "Integer" data type. One such shenanigan was you could have a Boolean expression that actually executes incorrectly (e.g: "true" and "true" = "false") in certain cases because it's performing a bitwise operation on their underlying (numeric) values (e.g. "3 and 4 = 0") and merely _casting_ the result as a logical True/False, instead of executing it as a logical operation to begin with.
@MatthewAhrensTech
@MatthewAhrensTech 2 ай бұрын
Lots of people are missing the major goal of refactoring away the boolean parameter. You aren't getting rid of the conditional logic. You are making the purpose of the functions smaller and decoupled rather than hiding two or more district behaviors behind a single function. The caller still has to know whether they want behavior A or behavior B. But instead of: behavior(...., true) vs behavior(...,false) Where I have to go look up the docs to see which is which... Why not just have: behaviorA(...) behaviorB(...) And the name tells me the cases. The OO designer would go a step further. Make an interface for behavior(...) Make an A class Make a B class And now, in the future, if it wasn't a boolean client decision at all, but actually there was a secret, third thing, we can make a C class and we don't have to go change the signature of behavior(...).
@rmbl349
@rmbl349 2 ай бұрын
It's still academic nonsense and disconnected from reality.
@rmbl349
@rmbl349 2 ай бұрын
It's still academic nonsense and disconnected from reality.
@pudicio
@pudicio 2 ай бұрын
formatDoc(bool padTabs, bool useHyperlinks, bool allowNesting) : you are going to write 8 functions now?
@MatthewAhrensTech
@MatthewAhrensTech 2 ай бұрын
@pudicio I would probably use keyword args with defaults to document this configuration pattern if there are two or more flags (if I'm in doing procedural like in python or racket) or use the builder pattern with a setting function for each configuration option ( or configuration record/table) if I'm doing OO or similar. So no, not 8, since functions aren't the only abstraction in my toolbox. But I would still pick an abstraction so that the caller of my code doesn't deal with "naked boolean values" that they have to memorize the order and meaning of. Nielsen heuristic: recognition rather than recall. Let the interface tell you about itself.
@taragnor
@taragnor 2 ай бұрын
The thing is that usually in this case, you're not doing two totally different behaviors, you're having one slight modification to a longer behavior based on a switch. And you may have more than one switch, which makes breaking things up into multiple functions a nightmare.
@fg786
@fg786 2 ай бұрын
How does this advice line up with DRY? If a bool is a simple switch in a function to turn on/off some feature or additional calculation I now create 2 functions that are probably the same code apart from 2 lines or so that he probably thinks is way too long in the first place.
@redhotbits
@redhotbits 2 ай бұрын
you ask same question as my dumb colleagues. you assume that both code branches are some garbage code, but they are not, most of code is reused. And how bool makes it DRY?
@oli_dev
@oli_dev 2 ай бұрын
Use helper functions, or better, call one function from inside the other
@Jabberwockybird
@Jabberwockybird 2 ай бұрын
Don't be dogmatic with DRY. WET is better than dry
@redhotbits
@redhotbits 2 ай бұрын
@@Jabberwockybirdnot always but yes in some cases. SOLID principles are not the only ones. anyway, bool arguments has almost nothing to do with DRY but some peiple make wrong conclusions infact avoiding bool arguments can promote DRY
@redhotbits
@redhotbits 2 ай бұрын
then your functions are spageti code, split them into more
@stivvits1067
@stivvits1067 2 ай бұрын
Just imagine how much extra work was made by the teams across the world under the influence of Uncle Bob. He might the single most net negative person in the industry.
@RusuTraianCristian
@RusuTraianCristian Ай бұрын
If you don't pass boolean to a fn because you wanna avoid if/else inside said fn, then you still need to check (do an if/else) outside the fn, to pass either false or true to on of the two functions (the alternatives). I'd say that's...odd.
@rafabo
@rafabo 2 ай бұрын
Please guys, what's the name of this talk? I'd like to watch it full and not cutet in clips Thanks
@holger_p
@holger_p 2 ай бұрын
For your pattern, your argument is correct. I would rather avoid it, because the meaning of the content of a boolean, is hidden in the variable/argument name. While an integer like "7" still holds the information, something has been counted here, true or false have absolutly no meaning, enabled=true or disabled=true ? the meaning is hidden in the variable name. So the alternative is to replace boolean with self defined enum {enabled, disabled}, it avoids many confusions, and assigments from one bool variable to another bool variable, who have a completly different meaning. Compiler would not strike on Enabled=Disabled nor Enabled=!Disabled, if everything is just bool.
@MortyCJ
@MortyCJ 2 ай бұрын
If the Boolean logic is removed from a function and converted into two function, isn’t that just moving condition to the caller? The caller then has to decide which function to call, placing the burden on it instead of (presumably) the more sensible location?
@TheMisterNebo
@TheMisterNebo 2 ай бұрын
So many 'experts' that tell us not to do certain things, or to only use certain things. Code however you like. The best code is code that works for you - there's plenty of benefits to use Functional over OOP in certain cases, and there's plenty of reasons to use booleans as parameters, there's even good reason to write difficult to read code and even 'spaghetti code' has a place (job security for instance). There's a place for everything.
@redhotbits
@redhotbits 2 ай бұрын
haha job security wins. bool arguments are good for the economy 😂
@samsorge27
@samsorge27 2 ай бұрын
Doesn't writing two similar functions instead of one, with a boolean passed in, conflict with the DRY principle? How do i decide which which principle to prioritize?
@pmkaboo2446
@pmkaboo2446 Ай бұрын
use your head and write code that will make the day better, not worse, for the next person who needs to change it.
@kowboy702
@kowboy702 2 ай бұрын
I don’t understand how not passing the Boolean is functionally better (other than readability). If you create two versions of the function, then the caller still has to do the if comparison to choose the function. But now you have the added complexity of maintaining two functions with similar code
@lukivan8
@lukivan8 2 ай бұрын
That is why pattern matching in function head is the best language feature of elixir. A lot of the time this boolean argument is replaced with guard
@DarkD112
@DarkD112 Ай бұрын
I came into this thinking it was going to be some explanation on how to debate someone with a really exotic tagline. I haven't touched programming in like a decade. Don't know how youtube decided to recommend me this.
@n0xeris
@n0xeris Ай бұрын
you avoid an if statement inside the function, by using an if statement to know which function to call when both operate on the same problem. brilliant.
@jameslay6505
@jameslay6505 2 ай бұрын
To help illustrate the problem, let's go the other extreme - ONLY EVER CREATE ONE FUNCTION and "select" the behavior you want using a combination of flags. So instead of "add(a, b), sub(a, b), email(to, fr, subj, msg), commit_db()... etc" you have "dothing(a, b, c="", d="", is_add=false, is_sub=false, is_email=false, is_commit_db=false)". This is kinda something that really happens in the wild and why Uncle Bob is bringing it up. Imagine how large dothing() is and how confusing it is to work with that function. All the code is sharing scope and might be reusing variables and what not and now if you need to add another feature to this function, well, you have to understand all the other functions it embodies. Instead of a simple 2 min change you've just wasted 2 hours figuring out why the `if (is_commit_db)` branch is using variables that also seem to be used in the `is_email` branch.
@dannymaher7766
@dannymaher7766 2 ай бұрын
This does not make sense at all, you will still need an if statement somewhere regardless so he is essentially creating 2 methods with an if statement in his recommendation rather than 1 method and an if statement. This would get even worse as you would likely need to make a method that both methods call to avoid repeating code
@lordkata1
@lordkata1 Ай бұрын
it’s more about making the code readable and avoiding bugs caused by code complexity. The smaller the function, with the right name and with fewer if statements can help a lot with preventing bugs.
@philperry6564
@philperry6564 3 күн бұрын
@@lordkata1 You don't make code more readable by splitting logical blocks into individual functions.
@DinoDiniProductions
@DinoDiniProductions Ай бұрын
Boolean arguments are always a bad idea, because things in life are rarely just 1 or 0
@PKMartin
@PKMartin Ай бұрын
Readability: absolutely agree. Used named parameters f(reverse=True) or enum values f(order.REVERSE), don't put True or False in your arguments list. Control flow? I disagree. What if the if code is in the middle of a function, I should write two 90% identical functions with one different block? DRY. What if the test for which branch to take involves more factors than just the boolean? Do I need to say if(boolArgument && isLeapYear() && temperature < 20) every time I decide which of the functions to call? DRY. What if I need to invert the sense of the flag - change one function or n function calls? DRY.
@brainmaxxing1
@brainmaxxing1 Ай бұрын
You would refactor to have a base function that does the 90% and then write the two branches as separate functions
@iamelonmusk9501
@iamelonmusk9501 Ай бұрын
So when I ask ChatGPT to generate functions for me, I should specify not to use boolean? Got it!
@debasishraychawdhuri
@debasishraychawdhuri Ай бұрын
When you have never written code that runs in production, this argument holds. A boolean can come from a configuration. Even if I am going to write two functions I am not gonna duplicate all of that code just so that I do not have to have an if condition.
@vlc-cosplayer
@vlc-cosplayer 2 ай бұрын
"Use as few booleans as possible, but not fewer than that."
@istegal8079
@istegal8079 9 ай бұрын
I sometimes do these booleans in functions. I’ll try avoiding them, because i don’t like them either. But how would I do that if the if statement is buried deeper down? split it into even more functions?
@official.mikilio
@official.mikilio 9 ай бұрын
It doesn't matter there are always only two versions of the function, one where it's true and one where it's false.
@myPrzeslaw
@myPrzeslaw 7 ай бұрын
If you can split the function into more smaller functions it suggests that the original function wasn't a single-responsible one. So yeah, feel free to split them. Unless you see some profit from keeping that bigger multi-responsible one.
@animuspexus
@animuspexus 2 ай бұрын
first they say to avoid gotos, then they say to avoid booleans. what next? - avoid c/c++?
@animuspexus
@animuspexus 2 ай бұрын
rust users incomming 3.. 2.. 1..
@dummypg6129
@dummypg6129 2 ай бұрын
Our senior dev uses int 0/1 is that ok?
@faximori
@faximori 2 ай бұрын
I would say that this make sense ONLY IF the function is longer than the screen height. This boolean can help to divide the code onto smaller pieces. But what about boolean without if? C# height = pageSize=="A3" ? 100: 250;
@amoineau
@amoineau 2 ай бұрын
About the second point, I do hate function with output arguments because they are messy to understand and to use... but what other option do we have if there are more than 1 element to return ? Create a structure just for the return type of this function ?
@distrologic2925
@distrologic2925 2 ай бұрын
Linux command flags should all be individual commands for each of their permutations, got it
@anibaldk
@anibaldk Ай бұрын
A small clarification is in order: Nothing wrong with booleans to guid control flow but try to keep them in a private implementation and expose functions in your API without such argument. THAT, in my opinion is the key. Booleans can help you with the DRY (Don't Repeat Yourself) approach but that should be shielded - if possible - from the caller.
@giffardjustin
@giffardjustin 2 ай бұрын
holy crap... the panning on this video's audio... what the heck?
@gabiold
@gabiold Ай бұрын
In my opjnion, using a pure boolean is a readability issue, unless the value indeed has a pure unitless logic meaning. Eg. if the argument chooses between two behaviors, then eg. setHeatingMode(true) is quite hard to figure out what it does until you look up the function's definition or documentation. If you'd rather declare an enum with the specific naming, like setHeatingMode(HeatingMode.night) then you don't even need to know the function, it's self-explanatory. I also don't quite like "one-side-biased" naming, when both options are equally frequent and normal: eg. setNightMode(true). In this case it is ambiguous that when it is NOT in night mode, it is in day mode then, and that's it, or it just disables the "night" component of a mode-set and there are other functions for other modes? One-side-biased is great if one of the options is exceptional, eg. disableUserInterface(true) when the user interface should be enabled most of the time, just has to be disabled under very specific circumstances. Generally if you screw around to come up with a great function name, then it is an indicator that probably the concept of the functipn is not the greatest...
@serdarekid
@serdarekid 2 ай бұрын
I wish the sound was clearer
@rumble_bird
@rumble_bird 2 ай бұрын
I didn't really understood the example in video about output arguments, my understanding is that it's like in C or C++ when you pass the pointer (read / write reference) to a function (void f(auto a, auto b, auto& result)) and then collect result from the parameter (int a = 4, b = 2, result = 0; f(a, b, result); std::print(result)) something along this lines. This is indeed really confusing and most of the times it's better nowadays to create a structure from return and the destruct it. (Result f(a, b); ... auto [result1, result2] = f(4, 2))
@ytano5782
@ytano5782 2 ай бұрын
I code in C/C++ close to the hardware and from my pov bool is the most useless datatype. If I want to save memory, then I work directly with bits. If it should be more readable, I use enums.
@GuillermoH77
@GuillermoH77 2 ай бұрын
Bool in C++ is somewhat limited and odd because of C / C++ doctrine of “everything must be addressable”. Which in turn, has forced virtually all modern CPUs to support byte level addressing… which is not the most efficient thing, to be honest. C++ doesn’t do a very good job with booleans.
@giornikitop5373
@giornikitop5373 Ай бұрын
@@GuillermoH77 byte level addressing is not a c/c++ fault.
@GuillermoH77
@GuillermoH77 Ай бұрын
@@giornikitop5373 are you sure? Do you think that some company which wants to create a new processor architecture would dare to do something that is incompatible with C? C puts a lot of requirements on hardware that in 1973 were probably very reasonable, but 50+ years later may have become a bit old & limiting.
@giornikitop5373
@giornikitop5373 Ай бұрын
@@GuillermoH77 cpus always had byte addressing anyway, no matter what c or any other language required. is it efficient? no, it never was. is it necessary? unfortunatelly, yeah.
@giornikitop5373
@giornikitop5373 Ай бұрын
bool is a reminant of the old era where memory capacity was very limited. languages tried to hit a balance between saving mem and easyness. nowadays bools are kept for compatibility. it depends on the needs but most software now uses a custom 4-byte var, to have more options and help with alignment.
@roto6500
@roto6500 2 ай бұрын
I'm not a genius but my brain can easily read code where it branches based on a boolean. And how do we know this is BOB and not 8O8?
@JumbaJumby
@JumbaJumby Ай бұрын
For people saying 'Great now I have 8 functions instead of one', the video's advice isn't 100% literal and there are different methods for breaking down your booleans. The general principle that should be followed is reducing the complexity and breadth of the work your functions are doing. Maybe you have 3 booleans passed in that would be 8 functions if split as-is, but perhaps one of those is better as an integer and is better utilized in a math expression than a branch. And maybe one of those booleans is logic I want to do sometimes but not always, in which case you can just split that logic off into its own function and call it when you need it. The name of the game is finding the most logical places to divide your code into functions that minimizes the permutations in which one function can do any given thing, such that you can simply read the code from top to bottom and understand the flow without needing to excessively investigate the arguments or inner workings. Boolean arguments are not outright evil, but they are an indicator that your structuring could be better, and that in the near future you may be adding more booleans, or you'll need another function that does the same thing but with some other difference. They bloat heavily and paradoxically can lead to larger, harder to read code.
@thomsencummings8471
@thomsencummings8471 2 ай бұрын
people are like "where do i put the bool then?". keep it in the function it was created! don't PASS it into a function, call two different functions when it gets created. execute control flow where control flow is created, not further down the execution path
@redhotbits
@redhotbits 2 ай бұрын
yes if bool is a result of an expression
@julendominadas4040
@julendominadas4040 Ай бұрын
okey marting we also should make a new function for each FLAG
@minoo1160
@minoo1160 2 ай бұрын
I don't understand the last thing
@2nolhta
@2nolhta Ай бұрын
Imagine naming a single report variations just because booleans control that it should be outputted bw or color, with or without summary lines, with or without an end summary line, ...
@podell111
@podell111 2 ай бұрын
Nah it’s over optimization. Write code that works
@henrycgs
@henrycgs 2 ай бұрын
oh that's just uncle bob. he does that. don't mind him.
@ibrozdemir
@ibrozdemir Ай бұрын
good.. instead of writing "if" inside that function, you are going to write that "if" inside parent function.. and why just booleans, why not every other parameters, for example used for switch, like enums, write 10 different functions for 10 different enum posibilities.. again you will put that switch inside the parent function
@aliyavarguluzada6123
@aliyavarguluzada6123 2 ай бұрын
I'll keep doing it.
@Bedfford
@Bedfford 2 ай бұрын
maybe true or maybe false XD. But one thing is a fact, many young programmers don't know anything about Boolean Algebra and their maths/calculus abilities are very low. How they understand and solve complex engineering problems with code?
@MerrickKing
@MerrickKing 2 ай бұрын
You've literally just lifted the if/else up a level out of the function and then created a second function...
@LarsHHoog
@LarsHHoog 2 ай бұрын
Please consult an audio technician to show you how you set the pan, levels and other vital qualities.
@mptest7461
@mptest7461 5 күн бұрын
Even if Dev Tools is right in some aspects of the pinned comment, what I'm still missing in Uncle's speech is presenting the alternative and comparing advantages and disadvantages of both. Repeating "this is awkward, this is rude" is not really educational.
@ricardocreemers
@ricardocreemers 2 ай бұрын
Could be better without the over dramatic music. I get it to make it less dry. But it was distracting.
@JonHuhnMedical
@JonHuhnMedical 2 ай бұрын
Some well placed comments solve these issues. It baffles me how few devs actually document their thought process.
@ShamerGamerJM
@ShamerGamerJM 2 ай бұрын
while more comments definetely can help, i think i can agree with the video to a certain extent, to at least that code should be better formatted as to make it so that few comments are really needed to be able to understand something
@makeavoy
@makeavoy 2 ай бұрын
Disregarding the non-issue bool param, can we talk about passing an object to mutate inside a function? Anyone that's written a single line of C/C++/Rust/Zig will tell you how not only useful that is but literally required. If you want fast code you want to not be creating whole new objects for every function, memory allocation is slow. you want to mutate existing ones. Even JavaScript takes advantage of this. Three.js recently started using more efficient buffers for holding values and a lot of functions let you pass in existing ones to to reduce ops.
@runek75
@runek75 Ай бұрын
That was funny, I wrote a comment yesterday, really about new programmers today that don't know how to read code. It was deleted some how :D It didn't have bad words or anything. Is uncle bob on the elite team or sumthin?
@RodrigoFavarete
@RodrigoFavarete 2 ай бұрын
“Don't organize your code to avoid huge functions, that's rude”
@arnaudparan1419
@arnaudparan1419 2 ай бұрын
I love uncle bob and read his books when I was a kid but let's be honest, he was already outdated 10 years ago
@Jabberwockybird
@Jabberwockybird 2 ай бұрын
This advice still holds up. I work on modern bloated js frameworks, and they can quickly get out of hand with too many boolean flags
@redhotbits
@redhotbits 2 ай бұрын
his books are for absolute beginners in an environment that has java only
@MrTimCypher
@MrTimCypher 6 күн бұрын
I never pass booleans into a function. I always pass in an array…of booleans.
@zool201975
@zool201975 2 ай бұрын
if a bool is the only argument i could agree unless the code would be too long and a function would be descriptive of what is happening. as for the function only returning an argument. i have no idea why anyone would do that unless its a placeholder for a callback and you do not want to add an if statement to check for a callback. people add descriptions to functions along with other info with /** to have the IDE elaborate the functionality for a potential callback or a function that has a bool. if not for that i have not come across other reasons.
@archilzhvania6242
@archilzhvania6242 2 ай бұрын
It's rude to add music where unnecessary
@Redingold
@Redingold Ай бұрын
I do the same for int parameters. Why write one function with potentially complex behaviour when you could write 4294967296 straightforward ones?
@karltheodorruby8518
@karltheodorruby8518 Ай бұрын
why the epic music lmao
@ricardoolivo9350
@ricardoolivo9350 Ай бұрын
the answer is, as usual, "it depends" or "yeah, sometimes"
@mepipe7705
@mepipe7705 2 ай бұрын
Nice talk. But this epic music in the background is a bit distracting to me
@umeshkumarasamy6608
@umeshkumarasamy6608 2 ай бұрын
Principle of least surprise 👍🙏
@hoefkensj
@hoefkensj Ай бұрын
never heard of branchless programming apparently , in wich case there wont be an if else int he function and your splitting up a fucntion because of it makes stuff more complicated than it needed be
"Clean" Code, Horrible Performance
22:41
Molly Rocket
Рет қаралды 941 М.
AI Is Not Designed for You
8:29
No Boilerplate
Рет қаралды 336 М.
Гениальное изобретение из обычного стаканчика!
00:31
Лютая физика | Олимпиадная физика
Рет қаралды 4,8 МЛН
小丑女COCO的审判。#天使 #小丑 #超人不会飞
00:53
超人不会飞
Рет қаралды 16 МЛН
It’s all not real
00:15
V.A. show / Магика
Рет қаралды 20 МЛН
REAL or FAKE? #beatbox #tiktok
01:03
BeatboxJCOP
Рет қаралды 18 МЛН
The symptoms of bad code - Robert C. Martin (Uncle Bob)
5:42
Dev Tools Made Simple
Рет қаралды 32 М.
Naming Things in Code
7:25
CodeAesthetic
Рет қаралды 2,3 МЛН
Why Just In Time Coding Is More Effective
7:36
Senior Code Review Buddy
Рет қаралды 6 М.
7 Design Patterns EVERY Developer Should Know
23:09
ForrestKnight
Рет қаралды 220 М.
I Interviewed Uncle Bob
1:11:07
ThePrimeTime
Рет қаралды 430 М.
Microservices are Technical Debt
31:59
NeetCodeIO
Рет қаралды 741 М.
My 10 “Clean” Code Principles (Start These Now)
15:12
Conner Ardman
Рет қаралды 317 М.
Clean Code - Uncle Bob / Lesson 1
1:48:42
UnityCoin
Рет қаралды 2 МЛН
8 Data Structures Every Programmer Should Know
17:09
ForrestKnight
Рет қаралды 249 М.
Гениальное изобретение из обычного стаканчика!
00:31
Лютая физика | Олимпиадная физика
Рет қаралды 4,8 МЛН