Live data from Hacker News

Don't use booleans (2019)

luu.io

81–90 of 152 posts

Re: Don't use booleans (2019)

#81

Earlier quoted context omitted.

Why is defining an enum "unrealistic"? It's at most 4 lines of very simple code to define an enum that replaces a boolean.

Think about cases more complicated than passing a bare literal. // Booleans + Named Parameters foo(should_scrub=not options.scrubbing_disabled) // Single-Use Enum import ScrubbingOption, ShouldScrub; foo( if options.scrubbing == ScrubbingOption::Disabled { ShouldScrub::No } else { ShouldScrub::Yes } )

If you format the second example more sensibly:

    foo(options.scrubbing == ScrubbingOption::Disabled ? ShouldScrub::No : ShouldScrub::Yes)
it doesn't look much worse at all

Re: Don't use booleans (2019)

#82

Tangentially -- use languages that have great enum support. 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 versus SomeEnum containing a Missing variant. I usually lean towards Option but I wonder…

An Option has the advantage that you con chain it with other Option/Result operations like map, and_then, etc. I think this would be called being "monadic".

The advantage of Enum with Missing variant is that it's more expressive, and that you don't have to nest access in the Some matching.

Generally I prefer Option, and often you can match directly with Some(Variant) to avoid nested matches.

Re: Don't use booleans (2019)

#83

It seems it's not so much booleans than using unnamed parameters for option parameters. I find myself using this style in C, it does not prevent a mix-up if someone refuses to use named field designators but it works ok : 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) {…

If a giant meteor took out WG14 we might get named arguments in C

   modify_string(.str=str, .options = { .toggle_case = true, .strip_whitespace = false });

Re: Don't use booleans (2019)

#84

Tangentially -- use languages that have great enum support. 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 versus SomeEnum containing a Missing variant. I usually lean towards Option but I wonder…

> I'd like to see a strong opinion on Option versus SomeEnum containing a Missing variant.

Java $DAYJOB here. If I'm a caller, I probably won't realise that SomeEnum.Missing exists. I'll just see that a function accepts a SomeEnum (which I don't have) so I won't call it.

Re: Don't use booleans (2019)

#86

One thing that annoys me about enums is that I'm always afraid that I'll write code like @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?

Pattern-match over them and don't use a catch-all clause. Let your compiler emit warnings for unhandled cases.

Re: Don't use booleans (2019)

#87
post #71

Earlier quoted context omitted.

Same in Python, no? def foo(bar: Literal["active", "inactive"])

What's the best Python type checker these days? Seems like there are at least 4: Mypy, Pytype, Pyright, and Pyre

basedpyright:

https://github.com/DetachHead/basedpyright

(assuming you can't/don't use MSFT's pylance)

Re: Don't use booleans (2019)

#88

It seems it's not so much booleans than using unnamed parameters for option parameters. I find myself using this style in C, it does not prevent a mix-up if someone refuses to use named field designators but it works ok : 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) {…

> It seems it's not so much booleans than using unnamed parameters for option parameters

It's actually using unnamed parameters at all. While this issue is more frequent for boolean parameters, it can happen for integers or floating point numbers as well. We do a lot of numerics in C, and calls such as

    optimize_foo (&state, 0.3f, 1e-5f, 1.f);
have the same issues as mentioned in the post: Error prone, more difficult to review, more risky to refactor.

Re: Don't use booleans (2019)

#89

Earlier quoted context omitted.

Typescript is great for this. function operation(user: User, state: “active” | “inactive”): void Boom. Done. Enum defined. You want people to use enums? Remove all context switching from the definition process.

Ah I love Typescript (IMO JS is the best "scripting language" out there, and has been for a very long time, but that's a different discussion). That said, I hate that typescript has many ways of doing it. That's the biggest problem. There's: enum SomeEnum { First, Second, } const enum SomeConstEnum { A = 1, B = A * 2, } type SomeEnumType = "first" | "second"; const SomeObjectThatIsAnEnum = { "first": 1 "second": 2 }…

Typescript type system is probably gold standard, you can enforce so much statically

Re: Don't use booleans (2019)

#90
I’m reminded of what a beautiful language objective C is. It completely solves this problem. For example, take a look at this iOS method name (real Apple API):

initwithenablefan:enableAirConditioner:enableClimateControl:enableAutoMode:airCirculationMode:fanSpeedIndex:fanSpeedPercentage:relativeFanSpeedSetting:temperature:relativeTemperatureSetting:climateZone:

/s

Post reply on HN