Live data from Hacker News

Don't use booleans (2019)

luu.io

71–80 of 152 posts

Re: Don't use booleans (2019)

#71

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…

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.

Same in Python, no?

def foo(bar: Literal["active", "inactive"])

Re: Don't use booleans (2019)

#72

Earlier quoted context omitted.

Named parameters are easy enough to mimic in JS using objects and the spread operation function foo({bar, baz}) { ... } foo({bar: 1, baz: false})

I'm aware, but "mimic" is the key word here. Other languages are named-first. E.g. in Swift nobody is thinking "should I name this parameter?". They name it by default, because they have to choose an internal name anyway , and they only reach for the anonymous-parameter feature after explicitly considering "should I make this parameter anonymous?" In other words, this blog post is practically irrelevant to those lang…

I don't agree. One can easily imagine how the "a bool for every edge case" approach won't scale for long when extending an existing code base. Regardless if the language or IDE makes you see the names of the booleans or not. I think the author's point is not so much about the names but about abstraction and concepts. Slapping another bool parameter onto a function and bifurcating its behavior with an `if` is easy to do, but hard to refactor once this has been done a couple times to that function.

Re: Don't use booleans (2019)

#73
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) { /**/ }
            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 linter

Maybe 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

Re: Don't use booleans (2019)

#74

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…

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
    } as const

I always lean towards the `enum` keyword, because I am of the opinion that if you're optimizing for less generated JS (and enums are actually worth optimizing for in this way) you're probably using the wrong language to begin with (unless you're in the browser and have no choice, etc).

Re: Don't use booleans (2019)

#75
post #71

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.

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

Re: Don't use booleans (2019)

#76

The assumption being that the language you are using does not have named parameters. Something all modern languages have, except, as usual, the ones the world is built on (JS, Java).

If the method takes so many arguments that named parameters is necessary for readability, it is often a sign that the method is either too complex and should be split up, or that the method should accept a "config" record as a parameter. I this makes it clearer because you can group the parameters and give them meaning. Then you know that "url", "headers" and "body" belongs to the "request" record, while "customerId" and "taskId" are separate

Re: Don't use booleans (2019)

#77
This goes away in a language that allows arguments to name the parameters:

  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.

Re: Don't use booleans (2019)

#78

You can think of booleans as a built-in, two-value enum that has a common semantic meaning. Use booleans if this is suitable for your purpose; it will be suitable for many. That said... this article feels like a bit of a strawman. Does anyone by default use three booleans in cases that are arechetypical enums?

> You can think of booleans as a built-in, two-value enum that has a common semantic meaning.

I love it when a language's bool type is just a sum-type like the sum-types you define in user code, e.g. https://ocaml.org/manual/5.2/core.html#hevea_manual10. It's an indicator of a language with good foundations.

Re: Don't use booleans (2019)

#79
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?

Re: Don't use booleans (2019)

#80

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…

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.

That’s the worst way to define enums. Now you have to make sure your codebase is using the same string literals everywhere and carry the potentially long type definition to every parameter, variable or function return type. And no, compile-time checks won’t cover 100% of cases.
Post reply on HN