Don't Use Booleans
Using enums over booleans in programming enhances code readability, prevents errors, and improves API extendability. Enumerations reduce mistakes, simplify code maintenance, and elevate software quality efficiently.
Read original articleThe article discusses the advantages of using enums over booleans in programming. Enumerations are suggested as a better choice for improving code readability, ensuring explicit typing to prevent errors, and enhancing behavior-driven design and extendability of APIs. By replacing boolean parameters with enums, developers can enhance code clarity, reduce the risk of passing incorrect flags, and simplify the process of extending APIs without creating compatibility issues. The author emphasizes the benefits of enums in reducing errors, improving code maintainability, and enhancing the overall quality of software development. The use of enums is recommended as a valuable practice that offers low overhead and significant advantages in software engineering.
Related
Common Interface Mistakes in Go
The article delves into interface mistakes in Go programming, stressing understanding of behavior-driven, concise interfaces. It warns against excessive, non-specific interfaces and offers guidance from industry experts for improvement.
Elixir Anti-Patterns
The document discusses code-related anti-patterns in Elixir v1.18.0-dev, highlighting issues like comments overuse, complex 'with' expressions, dynamic atom creation, long parameter lists, and namespace conventions. It provides examples and refactoring suggestions to improve code quality and maintainability.
Weekend projects: getting silly with C
The C programming language's simplicity and expressiveness, despite quirks, influence other languages. Unconventional code structures showcase creativity and flexibility, promoting unique coding practices. Subscription for related content is encouraged.
Programmers Should Never Trust Anyone, Not Even Themselves
Programmers are warned to stay cautious and skeptical in software development. Abstractions simplify but can fail, requiring verification and testing to mitigate risks and improve coding reliability and skills.
I Probably Hate Writing Code in Your Favorite Language
The author critiques popular programming languages like Python and Java, favoring Elixir and Haskell for immutability and functional programming benefits. They emphasize personal language preferences for hobby projects, not sparking conflict.
Well you knew what was coming -- Rust enums are excellent[0], and so are Haskell's[1] (try and spot the difference between an enum and a record type!)... But that probably won't help you at $DAYJOB.
A bit more on topic though -- I'd like to see a strong opinion on Option<SomeEnum> versus SomeEnum containing a Missing variant. I usually lean towards Option<SomeEnum> but I wonder if there are any devout zero value proponents.
I don't like how golang does/requires zero values, but in more expressive languages I do waver sometime between Option<T> and T w/ a "missing" indicator variant inside.
[0]: https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html
fetch(accountId, history = true, details = false);
However, I would be opposed if this mechanism is permitted to perturb the order of fixed arguments. If history is the third argument, rather than the second, it should error.I.e. "history = true" means "we are passing true as the second parameter, which we believe to be called 'history', on penalty of error".
Fixed parameters having their names mentioned and checked should not be confused with the language feature of keyword parameters, which passes an unordered dictionary-like structure.
That said... this article feels like a bit of a strawman. Does anyone by default use three booleans in cases that are arechetypical enums?
https://existentialtype.wordpress.com/2011/03/15/boolean-bli...
typedef struct options_s {
bool toggle_case;
bool strip_whitespace;
} options_s;
char *modify_string(char *str, options_s options)
{
if (options.toggle_case) { /**/ }
if (options.strip_whitespace) { /**/ }
return str;
}
int main(void) {
char str[] = "Hacker News";
modify_string(str, (options_s){ .toggle_case = true, .strip_whitespace = false });
}
Now that I think of it it's probably trivial to forbid the use of struct literals without designated fields in code in a linterMaybe we get anonymous struct function parameter declaration with C32 ? :D
EDIT: I have been asking around to people fluent in standardese and if you leave out fields in a struct literal you are guaranteed they will be zeroed-out
foo(arg1: boolean, arg2: boolean, arg3: boolean)
Then when you call it it will look like foo(true, false, true) which is not great for readability. Instead I move all the arguments into an object which makes each field explicit. Ie.
foo({ arg1: true, arg2: false, arg3: true })
This also carries the advantage that you can quickly add/remove arguments without going through an arduous refactor.
Rules like this aren't that useful IMO. What if you have like a SetActive(bool active) method? Does this also get an enum? Should this be two methods? Blah blah blah. You can only cultivate taste with experience and consideration, not with rules. Everyone's seen codebases that followed all the rules but were still total messes. Or as Tool said: think for yourself; question authority.
I read about half of of submissions, I don't know if others also said all this already.
@enum MyEnum A B
sometest = x == A ? B
Which is correct but that one that I'll add new elements to the enum @enum MyEnum A B C
and forget to check if that code is still correct. Suggestions?typescript saves the day again
fetch(accountId: AccountId, options: {includeDisabled?: boolean, history?: boolean, details?: boolean})
Of course, doing this adds overhead to the developer at the time the code is written. Instead of just writing 'bool', you need to go into the header and define a new enum and decide what it and each of its entries will be named, and make sure that it is propagated up through any dependencies that will interact with that function and so on.
Frankly, that can be a lot more work - especially in a large legacy code base.
Sometimes just a simple Bool is easier.
use_boolean = false;
type boolean = (true, false, EFileNotFound)
initwithenablefan:enableAirConditioner:enableClimateControl:enableAutoMode:airCirculationMode:fanSpeedIndex:fanSpeedPercentage:relativeFanSpeedSetting:temperature:relativeTemperatureSetting:climateZone:
/s
Related
Common Interface Mistakes in Go
The article delves into interface mistakes in Go programming, stressing understanding of behavior-driven, concise interfaces. It warns against excessive, non-specific interfaces and offers guidance from industry experts for improvement.
Elixir Anti-Patterns
The document discusses code-related anti-patterns in Elixir v1.18.0-dev, highlighting issues like comments overuse, complex 'with' expressions, dynamic atom creation, long parameter lists, and namespace conventions. It provides examples and refactoring suggestions to improve code quality and maintainability.
Weekend projects: getting silly with C
The C programming language's simplicity and expressiveness, despite quirks, influence other languages. Unconventional code structures showcase creativity and flexibility, promoting unique coding practices. Subscription for related content is encouraged.
Programmers Should Never Trust Anyone, Not Even Themselves
Programmers are warned to stay cautious and skeptical in software development. Abstractions simplify but can fail, requiring verification and testing to mitigate risks and improve coding reliability and skills.
I Probably Hate Writing Code in Your Favorite Language
The author critiques popular programming languages like Python and Java, favoring Elixir and Haskell for immutability and functional programming benefits. They emphasize personal language preferences for hobby projects, not sparking conflict.