Ah, booleans. 0 or 1, true or false. Always either one of them, never something in between. So simple and predictable. At the end of the day, all c...
For further actions, you may consider blocking this person and/or reporting abuse
I find that quite often flags are added to toggle code at the end or at the beginning of a subroutine. For a simple example:
In these cases, the refactoring is quite easy: extract the common functionality into another subroutine:
When the code being toggled happens in the middle of the subroutine, it's often the kind of situation where passing a function as an argument is a better option:
Cases where neither of those apply, are often a sign of over-complicated program logic, or code that shouldn't be shared at all.
Note: examples in Lua because that's what I find easy to write.
But now you have the logic in two places, shouldn't you call one function from the other to avoid that?
Indeed, that was what I intended to do, but apparently I forgot to actually change that line after copy-pasting it. You're totally right in that this only makes sense when you actually use the subroutine with the extracted logic :D
yes, passing the function is what is described in the
inversion of control
article I linked to. Definitely worth a read, a very nice concept.Calling it "inversion of control" almost seems a bit weird to me because it implies that it is the "inverted" form of how it should normally be. But the example of a
select
(orfilter
or whatever one wants to call it) function makes it very obvious how it's really just another way to write a loop. It's not "inverted"; it's just normal control-flow.Definitely! I kinda omitted the fact that there are legit use-cases 😅, like if it's a boolean in a real-world scenario (enabled / disabled is a good example). I was more focussed on putting attention on wrong usages of booleans, because I think they outweigh the "real" booleans by a lot :)
see also the comment from @mcsee below: dev.to/mcsee/comment/1c1h8
I would say flags don't always have to be part of SRP as long as the "responsibility" is broad enough to fit it. Technically that function could have a single responsibility.
Like
class C
andclass D
extending fromclass B
whichextends A
.in such cases you can use polymorphic decorators
It is a balance between hated booleans and over design
if you need to put just one IF, I guess booleans would be ok. if you have several ones you should favor using polymorphism as stated in Dominik's article
A jumble of good points you have here.
I, myself, didn't realize my inner hate for Java's String stdlib was due to booleans. Reading Java code just simply put me off and I had no idea why.
Another point in case in C and C++: your system almost always allocates a WORD (32bits on 32bit system, 64bits on a 64bit system) for creating a variable on the stack. However, did you know that with the stdlib, the range of said bool is from 0-255? That's right - it's a byte. In a typical program you are likely to allocate a lot of bools. This is a lot of wasted space in my opinion. GCC will optimize a lot of situations like if statements down to a cmov instruction. However, if you call a function that isn't a leaf function
const char* formatMetric(int64_t value, bool isPercent);
then you bet its just a lot of wasted stack space. What's even worse, is you get a LOT of padding situations in structures.In a library I've developed and not released called CPO (a CLI application paradigm), you are rest assured that I use bitpacking on an int64_t (64bit systems) to ensure the density of the sheer amounts of booleans that appear in CLI applications.
Great article!
Great Article !!
Booleans are a a code smell
Code Smell 07 - Boolean Variables
Maxi Contieri ・ Oct 26 '20 ・ 1 min read
very nice, ♥️ your series. Also very good concept of exceptions for real world scenarios.