Live data from Hacker News

Get rid of those boolean function parameters (2015)

mortoray.com

51–60 of 119 posts

Re: Get rid of those boolean function parameters (2015)

#51
post #41
post #39

Named parameters misses the point. Functions should do one thing and only one thing. This is why we have cos, sin, and tan and not a universal function for trigonometry: trig(mode='cos', ...). Such functions often become cumbersome to use since they are essentially multiple functions baked into one.

Religiously splitting functions with boolean arguments doesn't always result in more maintainable code. Instead of trigonometry functions, how would you refactor JS's fetch() with many of its behaviour-altering flags?

> how would you refactor JS's fetch()

as @flavius29663 said (https://news.ycombinator.com/item?id=28593669) you can use the builder pattern

    FetchBuilder()
      .withUrl(ur)
      .withMode("cors")
      .withCache(true)
      .withHeader('Content-Type', 'application/json')
      .accept('*/*')
      .post()
      .then(response => response.json())
      .then(data => console.log(data));

Re: Get rid of those boolean function parameters (2015)

#52
post #33

Earlier quoted context omitted.

Fwiw, Ada does this too.

Does this feature have a general name? Swift users seem to call it "dot syntax", which is not a good name. I want to google "C++ should have " and find a proposal from 2013 that never moved forward, but "C++ should have dot syntax" is just silly.

It’s not just for enums in Swift, it’s applicable to all kinds of static functions, constants, initialisers. Has to be static (in the Swift/Java/etc sense) to work. Maybe “contextual members” or “contextual statics”. I like the latter.

Re: Get rid of those boolean function parameters (2015)

#53
In Delphi I try to use sets over boolean parameters. Then I can easily add new possible set members instead of introducing more parameters.

    type FuncParam = (fpDoThis, fpDoThat);
    type FuncParams = set of FuncParam;

    function MyFunc(arg1, arg2: integer; params: FuncParams): integer;
    begin
      result := 0;
      if (fpDoThis in params) then
         result := DoThis(arg1);
      ...
    end;

    // supply directly
    MyFunc(123, 42, [doThis, doThat]);

    // or indirectly
    params := [];
    if (condition) then
      Include(params, doThat);

    MyFunc(111, 222, params);
    

Delphi ain't the most elegant language out there, but the set functionality is pretty nice.

Re: Get rid of those boolean function parameters (2015)

#54
post #27

Earlier quoted context omitted.

In C++ I’ve gotten in the habit of `enum class is_gain : bool { no, yes };` so the call site is `v = calc_formula(ia, ib, is_gain::yes);`. An advantage is that such stron Boolean-like types can be passed repeatedly and maintain their type safety.

The 'require named argument' solution is less strong than the enum solution. (An enum is also available in python). Indeed re-use of the plain bool in Python is less clear, as is passing it on. This makes the enum the best solution. However, enum is also a heavy-duty solution. It requires slightly more typing, but more importantly, it requires exporting an enum to all call-sites. Both in C++ and in python this is not…

>... it requires exporting an enum to all call-sites. Both in C++ and in python this is not desirable.

Given the reasonable namespacing that C++ and python [modules] provide, and that you have to export the complete calling specification of the function to the caller anyway (whether it's an enum, a positional boolean or a keyword argument), what's the drawback of the enum option?

Re: Get rid of those boolean function parameters (2015)

#55
post #3

In python, I love keyword-only arguments for this. Then the caller has to write: v = calc_formula(ia, ib, is_gain=true) You also have the option of defining a default value for the argument so the old call-sites don't even need modification.

In C++ I’ve gotten in the habit of `enum class is_gain : bool { no, yes };` so the call site is `v = calc_formula(ia, ib, is_gain::yes);`. An advantage is that such stron Boolean-like types can be passed repeatedly and maintain their type safety.

A lightweight alternative I often use is to make a named constexpr at the callsite. `constexpr bool IS_GAIN = true; v = calc_formula(ia, ib, IS_GAIN);`

Re: Get rid of those boolean function parameters (2015)

#56

As pointed out in some of the article's comments, a much better solution would be if all languages allowed putting the name in front of function parameters (and while at it, also not enforce a specific parameter order and skip default-value parameters). A workaround in C99 (and more limited in C++20) is to use a single struct which bundles all the function parameters, and then use designated initialization, this also…

For C* langs you can just insert a block comment with the arg name: my_func(/*a_bool_flag*/ true, yadda);

The downside to this approach is it often doesn't survive refactors. People change the method signature, update call sites, and often ignore the comments. Named parameters avoid this downside, it's a real shame named parameters are not more common in languages.

Re: Get rid of those boolean function parameters (2015)

#57
post #56

Earlier quoted context omitted.

For C* langs you can just insert a block comment with the arg name: my_func(/*a_bool_flag*/ true, yadda);

The downside to this approach is it often doesn't survive refactors. People change the method signature, update call sites, and often ignore the comments. Named parameters avoid this downside, it's a real shame named parameters are not more common in languages.

Linters can check for this sort of thing, for example Error Prone[0] has a lint[1] for this.

Totally agree this is better to be in the language proper so we don't need this extra tooling.

[0]: https://errorprone.info

[1]: https://errorprone.info/bugpattern/ParameterName

Re: Get rid of those boolean function parameters (2015)

#58
post #17

Earlier quoted context omitted.

The point is that this is a presentation issue. There is nothing wrong with the model. It would not be impossible for the reviewing software to analyze source code and display named parameters.

That would require every bit of software that presents this program not only to understand my programming langauge, but also to have enough context on the rest of the program to actually recognize the function and know what each parameter represents. Not to mention, code is itself a presentation layer. Why would you put some presentation concerns in one layer (e.g. identifier names, indentation&styling), but others i…

this is true actually. every place we read code needs to also parse the code. it’s already happening today, that’s how you get syntax highlighting. the future of all code review in the browser is a more similar experience to coding in an ide. and eventually the browser will replace the ide (and you could say this is already happening too)

Re: Get rid of those boolean function parameters (2015)

#59
post #27

Earlier quoted context omitted.

In C++ I’ve gotten in the habit of `enum class is_gain : bool { no, yes };` so the call site is `v = calc_formula(ia, ib, is_gain::yes);`. An advantage is that such stron Boolean-like types can be passed repeatedly and maintain their type safety.

The 'require named argument' solution is less strong than the enum solution. (An enum is also available in python). Indeed re-use of the plain bool in Python is less clear, as is passing it on. This makes the enum the best solution. However, enum is also a heavy-duty solution. It requires slightly more typing, but more importantly, it requires exporting an enum to all call-sites. Both in C++ and in python this is not…

It's worth noting that in Python, the enum will be slower than using a bool (how much slower? I don't know - I haven't measured it), if for no other reason than the repeated name lookups. Is it worth fretting over for something that's called occasionally? Probably not. If it's something that's going to be called a lot, e.g. in a tight loop, then it's something to be concerned about.

Re: Get rid of those boolean function parameters (2015)

#60

What about copy pasting functions and make variants? With a hint in the name about what the variant does? Copy pasting and modifying seems like a safe low effort working solution. Is this considered bad practice?

Yes. It's not a bad first-pass, but it can easily lead to problems if there are too many instances of it. In particular, if there is any error in the initial program that's gone undetected or any change to the requirements that it implements, then you have to fix every single copy. Good luck.
Post reply on HN