PEP 285: Adding a bool type

Dan Smart cppdan at dansmart.com
Sat Apr 6 17:25:40 EST 2002


Laura Creighton <lac at strakt.com> wrote in 
news:mailman.1018120753.6552.python-list at python.org:

> Thank you very much for the reply.
> I just want to correct something you ascribed to me.
> 
>> I guess we'll have to agree to disagree here: I don't think that bools
>> are bad, either Python's variety or any other language's kind.  I've
>> seen your arguments, and they just don't convince me.  So be it. 
> 
> I think there is a time and a place for bools --  Describing things
> that have two states that can never, ever, have 3 or more states.  
> These things are vanishingly close to non-existent, unless you are
> a mathematician in which case you may be playing with these sorts
> of things all the time.  What I am trying to do is save people
> like Mark McEahern from his isValid function, which returns whether
> a username is valid or not.  On the day his boss demands a third
> value - valid-but-I-won't-let-you-in-anyway-you-didn't-pay-your-bill,
> he will thank me.
And on the day that a maintenance programmer comes to try and understand 
the obscene mess you have recommended, he will curse you. There are two 
correct solutions to the hypothetical problem you posed, neither of which 
involve isValid() (an intergatory function that obviously has a YES/NO 
answer) returning anything other than YES/NO.

The first is to add a second function isAllowedToLogin (another 
interogatory function that obviously has a YES/NO answer).

The second is to replace the isValid() function with a function like 
validateUser() which either returns OK or a failure reason. In fact I'd 
probably code it to return OK, or raise an exception, YMMV.

Both these alternative will involve refactoring the code to account for 
this change, but that is a GOOD THING, and was anyway required by your 
change. The difference being that both the above solutions accurately 
describe the requirements, where your solution obfuscates those 
requirements.

Another example you gave, that of isinstance, shows equally flawed 
reasoning. Either an object is an instance of a given class, or it isn't. 
It is a fact that instances of a class derived from the given class are 
also instances of the given class. I understand that there are times when 
it might be useful to differentiate between objects that are both instances 
of a given class and instances of a class that is derived from that class, 
and objects that are only instances of the given class, but this is a 
different question. Overriding the former question so that it also answers 
the second question *decreases* the clarity of code that has to deal with 
these issues; by (a) obscuring the intent of the question, readers now have 
to understand that a single question serves two purposes, and intuit which 
question was really being asked; and (b) forcing code that is only 
interested in the answer to the former question (which is the most likely 
case) to account for the fact that they also getting an answer to the 
second. As an aside there is another case that you failed to think of, you 
can modify the methods and variables of an instance of a class. Note that 
in this case isinstance is still a valid question which still only has a 
YES/NO answer, but it may be useful to have a third query to differentiate 
this case.

Your suggestion that very few questions only have YES/NO (or TRUE/FALSE) 
answers surpises me, I can think of several immediately: isValid(), 
isNonZero(), isModified(), isInstance(), contains(). In general if you 
discover that such a question turns out to be Yes/No/Maybe, it indicates 
that you either originally provided the wrong question, or that 
circumstances have changed such that a new question (or set thereof) would 
be more appropiate. In either case refactoring the code to reflect this 
change in reality/understanding is the correct thing to do. Changing the 
function to return extra state is hacking, and while there's a time and a 
place for hacking, suggesting that this is good design is almost as 
outrageous as suggesting that the function should have originally been 
written to make such hacking easier.

> 
> That is what I mean by teaching people not to use bools -- teaching
> when not to use them. This is very hard to teach.  I know it because
> I have been doing it for years and years.   I even know _why_ it is
> hard to teach, but that doesn't make it any easier.
> 
> Laura
> 
Perhaps you would be better off teaching them sound design, that code 
should accurately and concisely express both the problem it is trying to 
solve, and that solution; and that when the problem, or the authors 
understanding of the problem, changes, the code should be re-written to 
reflect that change.

Just in case you think I've missed something, I completely agree that:
    	Using bools to represent other bi-valued states (like color/side in 
chess) is terrible design.
    	Using the integer value of a bool (as in the isLeapYear example) is 
terrible design (although not because the number of days may not 0 or 1, 
but because such code doesn't say what it means).
    	Using bools as the return value of functions that are not directly 
enquiring as to whether a given assertion holds is almost certainly a 
mistake. Note that functions that are enquiring as to whether a given 
assertion holds should have an interogatory name that reflects that.
    	In particular, using a boolean return to indicate success/failure is 
almost certainly a mistake, as success/failure is not the same as 
true/false, and knowing what failed is usually important. This is probably 
the most difficult case, as there are rare cases where you are only 
interested in the two states, and there is a temptation to believe that in 
such cases there is an implicit question "wasThisSuccessful" which does 
have a Yes/No answer, this temptation should be resisted. It may be 
appropiate in such cases to provide a function like "succeeded()" which 
takes the return value of the function in question, and returns true/false.

Dan "It doesn't seem that hard to say when not to use bools, although of 
course if you include the cases where bools should be used, it gets much 
harder" Smart
-- 
Dan Smart. C++ Programming and Mentoring.
cppdan at dansmart.com
ADDvantaged



More information about the Python-list mailing list