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
@MrHaggyy4 күн бұрын
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.
@pikachufan253 күн бұрын
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...)
@user-sl6gn1ss8p13 күн бұрын
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.
@TheScottShepard7 күн бұрын
I identify as Boolean and it’s mean.
@ninobach74562 күн бұрын
True @@TheScottShepard
@BooleanDevКүн бұрын
@@TheScottShepardI am Boolean and I agree
@mepipe77052 сағат бұрын
You must be a strong character to stand that toxicity
@Zocress7 ай бұрын
My function names after this talk be like: copy_files_but_do_not_overwrite_older_files_but_do_override_if_file_is_smaller
@GiovanniCamellini24 күн бұрын
😂
@abiofficial-ws7pn22 күн бұрын
Actually I do that too. Good to know that I'm not the only one on the planet.
@saryakan20 күн бұрын
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.
@GiovanniCamellini20 күн бұрын
@@saryakan For some reasons this actually reminds the tax-loss harvesting structure that some trackers apply on portfolios with several different cryptocurrencies in it
@psychic887216 күн бұрын
You probably need to inject a function of when to overwrite instead of booleans
@ivantatarchuk69722 күн бұрын
Don't write code! The best code is that you have never written.
@programmer135618 күн бұрын
The best code is code that _you_ haven't written [hahahah, sorry, I had to]
@nyarlathotep720417 күн бұрын
TRUE
@user-sl6gn1ss8p13 күн бұрын
@@nyarlathotep7204 did you just use a boolean?
@vitobrx9 күн бұрын
Your sentence returns a True
@lpi37 күн бұрын
@@vitobrxbut there is no return operator. It looks like it returns void.
@MrKrtek0020 күн бұрын
can we have a little more dramatic music?
@louen841310 күн бұрын
I was kinda disappointed, was waiting for the swordfight to start at any moment...
@heyhoe1688 күн бұрын
@@louen8413 is this why you descended to a comment section?
@smort1235 күн бұрын
A bit more noise maybe?
@ekkehardehrenstein1808 сағат бұрын
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.
@mepipe77052 сағат бұрын
@@smort123a bit is a boolean and thus bad as an argument, as I understood
@MTAG13 күн бұрын
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.
@adamrussell6589 күн бұрын
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"?
@MTAG9 күн бұрын
@@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?
@mariusg88249 күн бұрын
I hate to agree with you, but I do. So much goldplating done on the wrong end.
@NerdyStarProductions7 күн бұрын
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.
@MTAG7 күн бұрын
@@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
@adambickford872014 күн бұрын
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.
@somestrangescotsman9 күн бұрын
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.
@lpi37 күн бұрын
Other words function should have only a bunch of assignments, one loop, one switch or one if else operator.
@ilonachan4 күн бұрын
but… coordinating work IS work. This principle can literally not work anywhere unless your "coordination" is completely trivial.
@adambickford87204 күн бұрын
@@ilonachan You have much more learning to do
@ilonachan4 күн бұрын
@@adambickford8720 can only be the response of someone who doesn't work with a real codebase
@sealsharp9 күн бұрын
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.
@ber299613 сағат бұрын
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(); }
@MsBukke10 күн бұрын
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
@alexchexes4 күн бұрын
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.
@makeavoy3 күн бұрын
@@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.
@DannoHung4 күн бұрын
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Күн бұрын
I actively use Python in my projects and already forgot that this was an issue in other languages. Keyword arguments are very useful
@yrds9610 күн бұрын
- Raises a problem - Doesn't come up with a solution. - Leaves Classic Uncle Bob
@alexcarrasquillo18 күн бұрын
Wait what? Didn't he just say to use 2 functions?
@preemtimhaxha53098 күн бұрын
@@alexcarrasquillo1you’re still gonna pass that boolean to the other function no?
@alexcarrasquillo18 күн бұрын
@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-jm2gx8 күн бұрын
@@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.
@WalderFrey8 күн бұрын
@@preemtimhaxha5309No
@stivvits1067Күн бұрын
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.
@jakobpederpettersen21799 күн бұрын
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.
@maskedredstonerproz5 күн бұрын
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
@VictorMartins2397 күн бұрын
so the reason is because he doesn't like it
@jameslay65054 күн бұрын
the reason is because it is a smell that your function is actually hiding several other functions within it
@ObesityStupidityКүн бұрын
@@jameslay6505 aaaand? What is the problem?
@byrey310 күн бұрын
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_dev9 күн бұрын
If you need to change something 8 times in this scenario, you probably arent using helper-functions when you should
@byrey39 күн бұрын
@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_dev9 күн бұрын
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)
@byrey39 күн бұрын
@oli_dev And finally you realice that this man is out of his mind trying to be controversial with this nonsense
@JacobNax8 күн бұрын
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
@JoepKockelkorn7 ай бұрын
I love the solution. Oh wait it isn’t mentioned. That’s rude…
@GoldenBeholden7 ай бұрын
He recommends putting each branch into its own function.
@Zocress7 ай бұрын
@@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.
@euunul7 ай бұрын
@@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?
@GoldenBeholden7 ай бұрын
@@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.
@unlomtrash7 ай бұрын
@@GoldenBeholdenI also do this when I have more than two if-branches
@holger_p7 күн бұрын
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.
@rmcgraw7943Ай бұрын
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.
@DeclanMBrennan29 күн бұрын
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.
@xucongzhan915116 күн бұрын
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.
@Jabberwockybird6 күн бұрын
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
@elijahshadbolt73345 күн бұрын
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.
@scheimong5 күн бұрын
@@elijahshadbolt7334Rust mentioned?
@meanmole32127 ай бұрын
Thanks, this vital insight helped me to code Quake 1 rendering engine, in fact it would have been impossible without this magnificent knowledge.
@MrMoralesOrlando2 күн бұрын
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 !
@TheNewton13 сағат бұрын
"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.
@TomZimmerman-s1q10 күн бұрын
This is such a non problem.
@lpi37 күн бұрын
It is problem when you have 6000 lines function
@jeremykiel67097 күн бұрын
@@lpi3 well maybe the solution is to not have a single 6000 line function in the first place
@lpi37 күн бұрын
@@jeremykiel6709 of course. It was not me, who wrote those lines.
@Flylikea2 күн бұрын
Depends... this if is_outlier: handle_outlier(data) is definitely not the same as this if data.quality == "outlier": handle_outlier(data)
@PaR20208 күн бұрын
This is a weird advise. So if I should not pass boolean where do i keep all the logic? In a top entry main() method?
@Jabberwockybird6 күн бұрын
This is referring to situations where the same code is handling two different use-cases. Imagine you have main and a different team on a different application has their own main. Now imagine you each have a different use-case. You could call Bob's function with like this. bobsfunland(true), and the other team would call bobsfunland(false). Or if it were refactored, you could call it like this. pAR2020UseCase() And the other team otherTeamUseCase()
@robertmainville48817 күн бұрын
Still trying to understand the argument against using a boolean in a function. 🤔
@Jabberwockybird6 күн бұрын
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
@leokiller123able9 күн бұрын
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)
@MatthewAhrensTech23 күн бұрын
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(...).
@rmbl34917 күн бұрын
It's still academic nonsense and disconnected from reality.
@rmbl34917 күн бұрын
It's still academic nonsense and disconnected from reality.
@pudicio16 күн бұрын
formatDoc(bool padTabs, bool useHyperlinks, bool allowNesting) : you are going to write 8 functions now?
@MatthewAhrensTech15 күн бұрын
@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.
@taragnor11 күн бұрын
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.
@mannyc66497 күн бұрын
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?
@nekononiaow6 күн бұрын
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.
@mannyc66496 күн бұрын
@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
@HollywoodCameraWork20 күн бұрын
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-451511 күн бұрын
Type Aliasing is a chore in most mainstream languages, F# has it greatly done
@holger_p7 күн бұрын
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).
@nekononiaow6 күн бұрын
How is it a composition nightmare? Composition is much simpler when the elements to compose do one single thing each.
@holger_p6 күн бұрын
@@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.
@FlowerBoyWorld10 күн бұрын
wtf booleans are literally the easiest things to read
@SmallSpoonBrigade17 сағат бұрын
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.
@lukkkasz3232 сағат бұрын
@@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.
@OhhCats8 күн бұрын
with bool arguments code runs too fast
@jbird44786 сағат бұрын
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".
@dannymaher776610 күн бұрын
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
@MortyCJ2 күн бұрын
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?
@rumble_birdСағат бұрын
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))
@barongerhardt7 күн бұрын
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.
@MrAlus310 күн бұрын
For kids in comments who don't get how to make a solution for this. When you pass a boolean into a method, you are basically passing a flag to switch something. What if you need more than ON/OFF? Then you will pass an enum, and what if you have an enum? You will have a switch statment, so kind of more if. You will get to the point when you should just have a switch with small methods that do specified stuff, not huge methods with booleans. In some cases ofc you can do this, when you are like 100% sure that it will be just ON/OFF like you coding hardware stuff. In other cases Uncle Bob is right and it's pretty straight forward what he says.
@Templarfreak8 күн бұрын
use booleans in a way where you only ever want an on/off. if you are using them in more ambiguous ways, you are using booleans wrong and should be using something like an enum instead. when do you ever need more than 2 states for whether a computer is on or off? you dont. if you need more information, such as _why_ the computer is off, then you use a different parameter, not try to encode it in the boolean or replace the boolean completely with the thing that encodes that extra information. it doesnt make sense and it makes more complicated and harder to read code.
@faximori8 күн бұрын
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;
@fg78611 күн бұрын
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.
@redhotbits9 күн бұрын
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_dev9 күн бұрын
Use helper functions, or better, call one function from inside the other
@Jabberwockybird6 күн бұрын
Don't be dogmatic with DRY. WET is better than dry
@redhotbits6 күн бұрын
@@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
@redhotbits6 күн бұрын
then your functions are spageti code, split them into more
@AutoGibbon3 күн бұрын
What's the battle music for? It's really annoying.
@podell1119 күн бұрын
Nah it’s over optimization. Write code that works
@zionklinger22645 күн бұрын
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
@samsorge27Сағат бұрын
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?
@abderrahmanemya66027 күн бұрын
i feel bad for all the people who had their time wasted for attending this. unless it was advertised as a pure comedy show
@ricardocreemers6 күн бұрын
Could be better without the over dramatic music. I get it to make it less dry. But it was distracting.
@TheMisterNebo7 күн бұрын
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.
@redhotbits6 күн бұрын
haha job security wins. bool arguments are good for the economy 😂
@thomsencummings84718 күн бұрын
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
@redhotbits6 күн бұрын
yes if bool is a result of an expression
@jameslay65054 күн бұрын
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.
@DataPastor13 күн бұрын
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.
@maximo66612 күн бұрын
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_p7 күн бұрын
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.
@roto65005 күн бұрын
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?
@victorbaxan74364 күн бұрын
Depending on who's reading the same piece of code, you'll have bored, surprised, amused, disappointed, defeated, angry etc, etc people.
@thyssenbot20 сағат бұрын
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.
@TheNewton13 сағат бұрын
named arguments , e.g. render(data, cache = false);
@ytano578210 күн бұрын
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.
@GuillermoH776 күн бұрын
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.
@АлексейСтафеев-р5б7 күн бұрын
I like this approach generally. But it is not absolute. We should not apply it everywhere. We always should think what we are doing. Let’s assume for example that we have a function which do something and it’s main logic it is about 99% of the function. And within this logic, deep inside, we have some condition, depending of the single flag. So what will cost less: not very beautiful solution with passing Bool argument into the function or duplicating 99% of the function to avoid Bool argument usage?
@makeavoy3 күн бұрын
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.
@James-l5s7k16 күн бұрын
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_dev9 күн бұрын
Yes, oh my gosh. I was looking for ages for this comment. I couldnt agree more
@rafabo2 күн бұрын
Please guys, what's the name of this talk? I'd like to watch it full and not cutet in clips Thanks
@animuspexusКүн бұрын
first they say to avoid gotos, then they say to avoid booleans. what next? - avoid c/c++?
@animuspexusКүн бұрын
rust users incomming 3.. 2.. 1..
@MerrickKing4 күн бұрын
You've literally just lifted the if/else up a level out of the function and then created a second function...
@Bedfford5 күн бұрын
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?
@johnlehew81923 күн бұрын
I avoid booleans, so many bugs are caused by devs misunderstanding them even though they are so simple
@archilzhvania62425 күн бұрын
It's rude to add music where unnecessary
@djee02Күн бұрын
Don't pass integers either, just write a function for every possible value
@arnaudparan141911 күн бұрын
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
@Jabberwockybird7 күн бұрын
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
@redhotbits6 күн бұрын
his books are for absolute beginners in an environment that has java only
@LarsHHoog5 күн бұрын
Please consult an audio technician to show you how you set the pan, levels and other vital qualities.
@distrologic29253 күн бұрын
Linux command flags should all be individual commands for each of their permutations, got it
@stephendolenc38159 күн бұрын
Bad background music. It's nearly impossible to watch
@JonHuhnMedical6 күн бұрын
Some well placed comments solve these issues. It baffles me how few devs actually document their thought process.
@MarioDanielCarugno6 күн бұрын
There always will be arguments for and against any rule... sometimes it feels like there are so many of them So try to follow fewer but important ones... write clear and small functions, use good names, try to make it readable as prose Pay attention to the code you write instead of making a bunch of code that is proof against bad programming
@vlc-cosplayer2 күн бұрын
"Use as few booleans as possible, but not fewer than that."
@matheusdardenne5 күн бұрын
True. If there is a boolean in the parameters, odds are that function is not respecting single-responsibility.
@asdfqwerty145877 ай бұрын
I don't see how doing something like: if(x) { DoSomething(); else { DoSomethingElse(); } Is really any better than putting the if statement inside of DoSomething(x); Either way the if statement is going to be there.. it's just a question of whether it's inside the function or outside of it, and you're likely repeating a lot of code completely unnecessarily by doing it that way (and I think it's more likely for the compiler to do a worse job of optimizing it if it's outside of the function too). If you're talking about passing in a constant true or false value into a function.. I think a lot of compilers actually already do the work of splitting it up into multiple functions if you're passing in constants into a function, but I guess that depends on the compiler.
@myPrzeslaw5 ай бұрын
But that's not the case. The fact that the function accepts the boolean argument that switches its behavior between DoSomething and DoSomenthingElse doesn't imply that context calling the function requires both of them and has parameter x that decides which one to use. You can have 1000 places in code that needs only DoSomething and 3000 places that need only DoSomethingElse. None of it needs a boolean argument. It just passes it because function requires it to determine which of two behaviors it has to choose. By the split into two separate functions (that possibly share common parts inside another private function), you have just 4000 places in code that use only what it needs and execute no if statements (neither inside or outside function). It's the difference between a pair of separate single-responsibility functions and a single, more general-purpose two-responsibility function.
@user-sl6gn1ss8p13 күн бұрын
@@myPrzeslaw Not two in your example, but a private function which holds some part in common which is used by two public functions which do basically the same and from which the user may or may not need to choose conditionally either way. If you think about amount of code, so long as two of those 4k places are conditional, you're having to maintain more conditional code already compared to the version where the more general function handles the split as well, or am I missing something? Another point could also be made about expressiveness, couldn't it? Like, if I see "DoSomething(x, optionalThing bool), I'm imidetially aware that "optionalThing" is a consideration. While with DoSomething I may also need compare to DoSomethingElse in order to realize the consideration is there. Especially so if you have a very wide interface, which you might very well have if you always follow this kind of logic.
@eslyricardoverano37033 күн бұрын
If we have two functions, then we are going to have an "if" somewhere before calling them. And what about boolean properties? like IsEnabled, setEnabled, etc, etc. Frameworks are full of them. All frameworks are bad!
@minoo11607 күн бұрын
I don't understand the last thing
@amoineau7 күн бұрын
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 ?
@raellawrence71169 күн бұрын
Disagree, at least in my use of JS. If you always run that function conditionally, then you can use the boolean and a guard clause to exit the function without branching. Otherwise, you need to add an if condition each and every time you call the function. Of course, it can default to true, so you don't need to use it at all, or purists can make a higher order function ie. doThing has conditionallyDoThing.
@yoavyanilov6 күн бұрын
IMHO it's such a weak argument against bool parameters. A much better argument would be to use enums instead of booleans. Every boolean is an enum waiting for a third value, your if/else will soon turn into a switch case or a "strategy pattern", and the last thing you want to have is multiple boolean parameters and a spaghetti of if/else statements in order to realize which internal logic(private function) to execute
@RetroFrequency4 күн бұрын
I honestly disagree about the "least surprise" bit, or rather, I don't disagree but making it a "rule" or "wisdom" is silly. It's effectively saying there's no better way to do something. Coders find shitty solutions to things, so I don't really agree that sticking to those solutions is a good thing. It might make your job easier as a code reviewer, but you're assuming everyone is stupid.
@zool20197510 күн бұрын
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.
@lukivan87 күн бұрын
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
@a2n0H9 сағат бұрын
And some people are wondering why code reviews are such a pain on some projects? 😅
@mepipe77053 сағат бұрын
Nice talk. But this epic music in the background is a bit distracting to me
@ISmellCapDog4 күн бұрын
And this is why trash code exists. When so many people try to influence how to do something better. You end up trying to blend all these skills together and code becomes unreadable. If you can’t read an if statement you shouldn’t be coding. To clarify your code add a to the point comment.
@istegal80797 ай бұрын
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.mikilio7 ай бұрын
It doesn't matter there are always only two versions of the function, one where it's true and one where it's false.
@myPrzeslaw5 ай бұрын
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.
@noli-timere-crede-tantum4 күн бұрын
Next advice from Bob: "do not use if statements in your code. That's rude. If you need to do something conditionally, your design is broken. Ruuude"
@giffardjustin3 күн бұрын
holy crap... the panning on this video's audio... what the heck?
@fray54179 күн бұрын
I'm starting to think Uncle Bob just has OCD?
@sergioengineer8 күн бұрын
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.
@Jabberwockybird6 күн бұрын
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.
@dummypg61295 күн бұрын
Our senior dev uses int 0/1 is that ok?
@atomicazure19 күн бұрын
Uncle Bob is good, but this is the stupidest thing I've heard in my 13 years of experience.
@holger_p7 күн бұрын
At least the generalization is. For his special pattern, he is completly right.
@itsjustramblings7 ай бұрын
i thought he was going to give some well nuanced technical answer but apparently the reason was to make code easier to read. lol. If you cannot differentiate an if statement then you need to move and become something else probably fail upwards and leave that role to someone who is keen. Why does he have a living room setup on stage? Is this some sort of tech talk show?
@DeclanMBrennan29 күн бұрын
I'm a life long developer and I know code readability is more important than almost anything else. Code that can't be read clearly and easily will be harder to maintain and that most certainly is rude. If you need to read the implementation of a function before you know what it does - that's a serious failure. It's like having to trace the wires from your automobile controls before being able to drive it.
@Mirko_ddd20 күн бұрын
Code readability is very important if you happen to read other people's code.
@itsjustramblings20 күн бұрын
code with comments adds clarity and readability can be achieved whether you have an if else or not. you are just pushing your bool check upstream in the code or somewhere else. what happens when your analyst or manager says we need to change that bool to an int or range values now? how does this even work without a branching call? please enlighten a stupid developer here.
@Mirko_ddd20 күн бұрын
@@itsjustramblings I think you are not paying attention to the details of the speech. He said that passing a bool as a method parameter is bad the 99% of the times because you will have to deal with if statements. Obviously the code will have some bool somewhere, but when it happens it is more descriptive to make another method for each of the two cases, instead of propagating the bool. And no please, don't comment your code, use more descriptive names for variables and methods.
@itsjustramblings20 күн бұрын
@@Mirko_ddd Sure thanks, but i ended up watching that video again after 7 months. Still, you are dealing with an if condition either way current or next function and if you have a lot of code in a method like he shows that has other problems not just readability.
@xtraszone2 күн бұрын
This logic doesn't work properly for building flutter UI as per specific conditions.
@ChrisStavros7 күн бұрын
Don't stop there: remove ALL the arguments. Then we CAN all just get along.
@serdarekid7 күн бұрын
I wish the sound was clearer
@adamrussell6589 күн бұрын
Keep it as simple as possible. Multiple ideas shouldnt be condensed into one function unless there is an actual reason to. Thats my opinion. Simple is almost always better.
@TheLaiKash4 күн бұрын
"Don't send arguments to hold what you're going to return" => JS callbacks don't like this
@alexandermglass8 күн бұрын
This generic advice of not using Boolean arguments is just way too simplistic. Everything should be done for a reason however. Example if you are using a Boolean to encapsulate some code in a function and there is a desire to avoid replication (DRY), boolean args are absolutely a valid choice. My advice is if you care about writing modular well written code, learn how to test almost everything. It forces good habits around properly sized abstractions.
@XiangWeiHuang8 күн бұрын
Following each and every of uncle bob's advices people would be writing zero code today
@corp-por23 сағат бұрын
The background music is rude. Let us just hear the talk only. Its rude, the video is rude.
@alfonszelicko79897 күн бұрын
that music in background is horrible :-) ...
@henrycgs4 күн бұрын
oh that's just uncle bob. he does that. don't mind him.
@I_am_Raziel24 күн бұрын
Nonsense.
@Jabberwockybird6 күн бұрын
You probably are thinking of a different example scenario. Or you have never seen the mess that can come from too mamy boolean flags. Or you're just a close minded jerk. Not sure which one