Live data from Hacker News

Get rid of those boolean function parameters (2015)

mortoray.com

41–50 of 119 posts

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

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

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

#42
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.

function pizza(boolean pepperoni, boolean bacon, boolean mushroom, boolean artichoke)

now becomes 16 distinct functions.

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

#43
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.

function pizza(boolean pepperoni, boolean bacon, boolean mushroom, boolean artichoke) now becomes 16 distinct functions.

    pizza_with_pepperoni_and_bacon_and_mushroom()
Wow glad I took out those boolean params!

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

#44
post #29

Earlier quoted context omitted.

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…

> every bit of software that presents this program not only to understand my programming language You can either change your program to fit existing tools, or you can build smarter tools. I prefer the latter. > code itself is a presentation layer Not for the tool it isn't edit: I think we can all agree that ideally we fix this in the language itself by adding optional named parameters

So your solution is to write code that is currently hard to read in the hope that someone will make a tool that presents it nicely in 10 years?

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

#45
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.

A valid use case for functions with many arguments are setup/init/creation functions which sometimes take dozens of configuration options. It's definitely better to do such setup operations in a single 'atomic' function call than spreading this out over dozens of configuration functions where it isn't clear when and in what order those should be called, or a combinatorial explosion of atomic setup functions, one for each valid combination of setup options.

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

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

Good rules of thumbs are given in the "Deciding which to use" section of the article. For the fetch() function, I'd keep most parameters as is since they don't change the essense of the function. But "cache" and "redirect" do (following redirects can cause N http requests rather than just one and using the cache perhaps 0) so I'd refactor them as new functions. Imagine adding retry functionality to the fetch() function using parameters. I think you can see how this leads to feature creep.

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

#47

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…

In JS we can use JSON/object literal syntax and object destructuring to serve a similar purpose: myFunc({ aBoolFlag : true, anotherBoolFlag : false, aString : "Hello World" }); const myFunc = ({ aBoolFlag, anotherBoolFlag, aString }) => { /* do something with them... */ };

I started doing this because of React but at this point ({}) is my default way of starting a function. The only thing I dislike is that it's not super ergonomic for explicit typescript declarations (but great when using typescript to check .js files).

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

#48
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.

Ada doesn't use the "dot syntax"; instead the enumeration literal is written as is without a dot. If I write:

    type Number_System is (Bin, Dec, Oct);
    type Month is (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec);

    procedure Foo (A: Number_System; B: Month);
Then this is a valid call:

    Foo( Dec, Dec )
https://godbolt.org/z/eP5qMj3K1

When the type is explicit, the Ada standard calls this a "Qualified expression". But I would just say that it is a kind of type inference for enumerations.

https://www.adaic.com/resources/add_content/standards/05aarm...

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

#49
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.

function pizza(boolean pepperoni, boolean bacon, boolean mushroom, boolean artichoke) now becomes 16 distinct functions.

pizza is very suitable for the builder pattern: CreatePizza() .WithBacon() .With(artichoke) .Build();

or any combination of the above: CreatePizza() .WithMussroom() .Build()

Even better, you can add new ingredients without changing any of the existing signatures: CreatePizza() .WithProsciuto() .WithTomatoSauce() .Build()

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

#50
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.

function pizza(boolean pepperoni, boolean bacon, boolean mushroom, boolean artichoke) now becomes 16 distinct functions.

not necessarly.

First of all, this

    function pizza(boolean pepperoni, boolean bacon, boolean mushroom, boolean artichoke)
breaks down when you want to add ham, potatoes and sausages to the pizza.

Secondly, you can optimize for the common case:

    fn pizza() # -> default pizza e.g. margherita
    fn pizza(list_of_ingredients) # -> your custom pizza

if you we are talking of simple functions and not more complex patterns, such as piping, in Elixir I would do

    pizza |> add_ham |> add_mushroom |> well_done
when using boolean parameters you are also passing down a lot of useless informations (a pizza with pepperoni would include 3 false just to remove the ingredients from the pizza and only one true) and confining yourself to a fixed set of options, that could possibly also represent an impossible state.
Post reply on HN