You-Dont-Know-JS icon indicating copy to clipboard operation
You-Dont-Know-JS copied to clipboard

Fixed onlyOne() not working as intended

Open tdamsma opened this issue 9 years ago • 3 comments

Fixed bug in function 'onlyOne', where onlyOne(2,0,0) would return false because it was adding the (non coerced) value of the argument to the sum. Also onlyOne(2,0,-1) would return true

tdamsma avatar Apr 08 '15 21:04 tdamsma

While this fix "works", it ends around the whole point, which is showing using coercion in the addition. Moreover, the intent is not really to generally have a utility that any kind of value can be passed to. It's mostly intended for values like true and false to be passed.

To be truly robust to other kinds of values, more logic would be required, and I'm not really sure I want to go down that road.

getify avatar May 10 '15 17:05 getify

I believe the function 'onlyOne' is intended to demonstrate the power/convenience of coercion. But this function assumes that the input is coercible to a boolean, but not a numerical value other than 0 or 1.

A common complaint is that implicit coercion makes it easy to write buggy code, as the assumptions about the input types are also very implicit. To me this example clearly demonstrates this pitfall of implicit coercion, so perhaps it's not so well suited in this chapter arguing the merits of coercion

tdamsma avatar May 26 '15 09:05 tdamsma

I can appreciate your concern.

But I don't think the pro-coercion message is "types don't matter" and "pass whatever the heck you want, we'll sort it out." I believe the responsible, balanced argument I'm making for pro-coercion is, "there are ways to change a value of one specific type to another specific type to help aid in tasks".

There no getting around that the design of functions, and as importantly the documentation about how to use them properly, is imperative in good software design. I would rarely try to design a function that handled every possible input value type gracefully, but rather would design it to handle the things that are allowed (or practical within scope), and choke on others.

So if I were to properly design an onlyOne(..) function for use in a library/framework (aka, for general consumption), instead of doing what you're suggesting, I would just simply throw an error if a non-boolean was encountered. But this exact task (checking if only one boolean is set) has actually been something I've needed in code before, and in that case, I knew all the inputs were already guaranteed to be boolean, so numbers weren't a concern.

I think the fix here is to add a note about this issue and this general commentary about function design but to leave the code alone. I will tag this for a second-edition refresh.

getify avatar May 26 '15 13:05 getify