Boolean parameters are wrong
by havoc
Today’s simple way to improve your code.
Say you’re reading a program and you see some lines like this:
new ArrayBlockingQueue(10, false); box.pack_start(child, false, true);
You don’t know what the booleans mean. Say you’re reading it and you see this:
new ArrayBlockingQueue(10, Policy.FAIR); box.pack_start(child, Packing.FILL);
Which is better?
There’s only one time that a boolean is OK, and that’s when the name of the method (or keyword, in a language that has keyword args) already describes it:
queue.setFair(false); box.set_expand(child, false);
Otherwise, no booleans. I know you’re too lazy to create an enum or flags type, but do it anyway.
Numeric types, for APIs where the number is expected to be a literal rather than a variable name, often have the same problem. But it’s a bit harder to solve in that case. The best solution may be for API users to use named constants.
Mystery-booleans are easy to avoid, though, so just do it.
I think boolean parameters are acceptable in a language that supports keyword arguments, such as Python, and where their use is encouraged to reduce ambiguity. In Python I would write: box.pack_start(child, expand=false, fill=true)
@Tack – I’d agree, as long as the parameter really is a boolean, and not just something that happens to have two allowed values. In Python, I *could* say sortAscending=True, but it’s arguably still better to sortOrder=ASCENDING.
yeah, I had a little parenthetical about that in the post
“(or keyword, in a language that has keyword args)”
Agreed – in Java code, I frequently use enums for the purpose. Passing SortOrder.ASCENDING is a lot easier to understand than passing ‘true’ and having to know that the parameter is called sortAscending.
For extra bonus, flags/enums is much more future-proof than booleans – that alone is a reason to prefer them.
Or use a language that describes parameters more verbosely like SmallTalk or ObjectiveC where this would like something along the lines of
[box pack_start:child pack:YES];
(Sorry, couldn’t resist since I am currently trying to get the hang of ObjectiveC …)
Your comments could also be applied to integer constant params when it’s not clear from the method name what the param in a specific position does. Or many other situations.
I always name boolean params (or other unclear params of any kind) with inline comments, e.g.
box.pack(child, /* expand = */ false, /* fill = */ true);
I often do that too, but I consider it a workaround for an annoying API.
See also: http://blogs.msdn.com/b/oldnewthing/archive/2006/08/28/728349.aspx
Not many new ideas from me apparently 😉
It’s also one of the .NET framework design guidelines – though I read it in the second edition of the of the book, you can find a draft here: http://blogs.msdn.com/b/brada/archive/2004/01/12/57922.aspx
[…] for designing APIs that use callbacks, to add to my inadvertent collection of posts about minor API design points. I’ve run into the “sync vs. async” callback issue many times in different places; […]