
Jonathan Lange wrote:
On 2/23/07, Neal Becker <ndbecker2@gmail.com> wrote:
bool ('False') True
Non-empty strings are considered True, empty strings are considered False. This is not a wart, as the behaviour matches that of other sequences.
Well consider this:
str (4) '4' int(str (4)) 4 str (False) 'False'
bool(str(False)) True
Doesn't this seem a bit inconsisent?

On 2/22/07, Neal Becker <ndbecker2@gmail.com> wrote:
Well consider this:
str (4) '4' int(str (4)) 4 str (False) 'False'
bool(str(False)) True
Doesn't this seem a bit inconsisent?
Virtually no python objects accept a stringified version of themselves in their constructor:
str({}) '{}' dict('{}') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: dictionary update sequence element #0 has length 1; 2 is required str([]) '[]' list('[]') ['[', ']']
Python is not Perl. -Mike

Mike Klaas wrote:
On 2/22/07, Neal Becker <ndbecker2@gmail.com> wrote:
Well consider this:
str (4) '4' int(str (4)) 4 str (False) 'False'
bool(str(False)) True
Doesn't this seem a bit inconsisent?
Virtually no python objects accept a stringified version of themselves in their constructor:
str({}) '{}' dict('{}') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: dictionary update sequence element #0 has length 1; 2 is required str([]) '[]' list('[]') ['[', ']']
Python is not Perl.
Except, all the numeric types do, including int, float, and complex. But not bool. In fact, this is not just academic. The fact that other numeric types act this way leaves a reasonable expectation that bool will. Instead, bool fails in _the worst possible way_: it silently gives a _wrong result_.

On 2/22/07, Neal Becker <ndbecker2@gmail.com> wrote:
Except, all the numeric types do, including int, float, and complex. But not bool.
Oh? In [5]: str(complex(1, 2)) Out[5]: '(1+2j)' In [6]: complex(str(complex(1, 2))) --------------------------------------------------------------------------- <type 'exceptions.ValueError'>: complex() arg is a malformed string
In fact, this is not just academic. The fact that other numeric types act this way leaves a reasonable expectation that bool will. Instead, bool fails in _the worst possible way_: it silently gives a _wrong result_.
I'd debate the assertion that 'bool' is a numeric type (despite being a subclass of int). For bool() to return anything other than the value of the python expression evaluated in boolean context would be _lunacy_ and there is absolutely no chance it that will be changed. -Mike

On 2/22/07, Neal Becker <ndbecker2@gmail.com> wrote:
Mike Klaas wrote:
On 2/22/07, Neal Becker <ndbecker2@gmail.com> wrote:
Well consider this:
str (4) '4' int(str (4)) 4 str (False) 'False'
bool(str(False)) True
Doesn't this seem a bit inconsisent?
Virtually no python objects accept a stringified version of themselves in their constructor:
str({}) '{}' dict('{}') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: dictionary update sequence element #0 has length 1; 2 is required str([]) '[]' list('[]') ['[', ']']
Python is not Perl.
Except, all the numeric types do, including int, float, and complex. But not bool. In fact, this is not just academic. The fact that other numeric types act this way leaves a reasonable expectation that bool will. Instead, bool fails in _the worst possible way_: it silently gives a _wrong result_.
i agree with mike; it would just be asking for trouble. (have you ever been bitten by the Perl behavior where the string '0' is considered false? it's a nasty, nasty problem to debug.) neal, you may be confusing the concepts of "convert data from one type to another" and "read the printed representation of data". ben

Neal Becker wrote:
Instead, bool fails in _the worst possible way_: it silently gives a _wrong result_.
I disagree with the word "fail" there; Python is working correctly. The behavior of converting expressions to a boolean is well-defined: http://docs.python.org/ref/Booleans.html Perhaps the behavior is unexpected or unwelcome--but it is *correct*. It's just one of those things about Python that one has to get used to; this is a side-effect of another, much more important principle. If you really want to turn the string "True" into True, use "eval". eval("4") -> 4 eval("True") -> True eval("{}") -> {} Perhaps it would be safest to cast the output of eval to bool: bool(eval("True")) -> True bool(eval("")) -> False Cheers, /larry/

Larry Hastings wrote:
Neal Becker wrote:
Instead, bool fails in _the worst possible way_: it silently gives a _wrong result_.
I disagree with the word "fail" there; Python is working correctly. The behavior of converting expressions to a boolean is well-defined: http://docs.python.org/ref/Booleans.html Perhaps the behavior is unexpected or unwelcome--but it is *correct*. It's just one of those things about Python that one has to get used to; this is a side-effect of another, much more important principle.
If you really want to turn the string "True" into True, use "eval". eval("4") -> 4 eval("True") -> True eval("{}") -> {} Perhaps it would be safest to cast the output of eval to bool: bool(eval("True")) -> True bool(eval("")) -> False
Cheers,
/larry/
In most cases like this you would not use string "True" or "False" but instead values True or False. In cases where you do have such strings You would probably be doing string comparisons anyway because there will most likely be other values to consider. if S == "True": .... Or use a dictionary to get predetermined values of expected strings. if svalues_dict["True"]: ... To Neal: Instead of being consistent with numeric types, bool is consistent in a different way. Think of it as len() having precedence over value if that helps.
bool('') False bool([]) False bool(()) False bool({}) False
bool('anything') True bool(['anything']) True bool(('anything',)) True bool({'any':'thing'}) True
This is really useful because you can do simple if tests to see if containers have anything in them. if somestring: ... if sometuple: ... if somelist: ... if somedict: ... If they do have contents of some some type, you then need to test the contents to see what is in them. Which might be a True or False values of some type. I suggest you take this to comp.lang.python to get further help with using bool. It is a good idea to test thoughts like this out there first. Cheers, Ron

This won't change so just get used to it. Please move any further discussion to c.l.py. -- --Guido van Rossum (home page: http://www.python.org/~guido/)

Neal Becker wrote:
The fact that other numeric types act this way leaves a reasonable expectation that bool will.
But bool isn't really a numeric type in the same way that the others are. It's only a subtype of int for historical reasons. If it had been a part of Python from the beginning, it probably would have been a separate type altogether. Hmmm... is that something that should be revisited in 3.0? -- Greg

Greg Ewing schrieb:
But bool isn't really a numeric type in the same way that the others are. It's only a subtype of int for historical reasons. If it had been a part of Python from the beginning, it probably would have been a separate type altogether.
Hmmm... is that something that should be revisited in 3.0?
I specifically asked the question when unifying ints and longs for 3.0 (as int went away, the question was what True and False ought to be). Guido pronounced that it is deliberate that they are "integer-like", and should continue to inherit from the integer type. One idiom that people use a lot is foo[b], where b is a boolean. Regards, Martin

Can anyone who is in favor of changing this please come up with a spec for the new bool() signature? What would you do for the most common use case of bool(), which is converting an arbitrary value to its Boolean equivalent without using an if test or the "not not x" hack? -- --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum schrieb:
Can anyone who is in favor of changing this please come up with a spec for the new bool() signature? What would you do for the most common use case of bool(), which is converting an arbitrary value to its Boolean equivalent without using an if test or the "not not x" hack?
I think this subthread doesn't propose to change bool(), but only to stop inheriting bool from int, while giving bools an __index__ method that returns 0 or 1 to still allow them being used as list indices. The obvious consequence would be that arithmetic wouldn't work any longer with bools involved. Also, mapping access or set membership wouldn't work like now,
d = {1: 2} d[True] 2 True in set([1]) True
but that would only be logical. Georg

On 2/24/07, Georg Brandl <g.brandl@gmx.net> wrote:
Guido van Rossum schrieb:
Can anyone who is in favor of changing this please come up with a spec for the new bool() signature? What would you do for the most common use case of bool(), which is converting an arbitrary value to its Boolean equivalent without using an if test or the "not not x" hack?
I think this subthread doesn't propose to change bool(), but only to stop inheriting bool from int, while giving bools an __index__ method that returns 0 or 1 to still allow them being used as list indices.
The obvious consequence would be that arithmetic wouldn't work any longer with bools involved.
Also, mapping access or set membership wouldn't work like now,
d = {1: 2} d[True] 2 True in set([1]) True
but that would only be logical.
How would this change be helpful? I'm utterly mystified by these suggestions that bool would be more useful if it didn't behave like an int in arithmetic. On 2/24/07, skip@pobox.com <skip@pobox.com> wrote:
Neal> Except, all the numeric types do, including int, float, and Neal> complex. But not bool.
The fact that bool is a subclass of int is more historic than necessary. If not for Python's long usage of 0 and 1 to be the canonical False and True, I suspect that bool might have been implemented as a new standalone type.
Not necessarily. I really like the idea that bool is embedded in int, just like int is embedded in float (real), and real is embedded in complex. The construction signature is a different issue -- some people seem to forget that constructor signatures don't need to match their base class; it's not required by Liskov substitutability. -- --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum wrote:
How would this change be helpful? I'm utterly mystified by these suggestions that bool would be more useful if it didn't behave like an int in arithmetic.
I think there's a desire by some people to get rid of unnecessary conceptual baggage left over for historical reasons. Those people are mystified as to why anyone would *want* a boolean to behave like an int. Personally I'm +0 on this. I wouldn't object if it happened, but I'm not pushing for it. -- Greg

Guido van Rossum wrote:
How would this change be helpful? I'm utterly mystified by these suggestions that bool would be more useful if it didn't behave like an int in arithmetic.
I don't think anyones really saying it would be more useful, it obviously wouldn't, since like Greg said, it wouldn't work in mapping access or set membership like it does now. I think it would be more readable though, since thinks like this:
True in set([1]) True
or that 5+True is equal to 6 aren't necessarily obvious to someone who doesn't know that True evaluates to 1.
The fact that bool is a subclass of int is more historic than necessary. If not for Python's long usage of 0 and 1 to be the canonical False and True, I suspect that bool might have been implemented as a new standalone type.
Not necessarily. I really like the idea that bool is embedded in int, just like int is embedded in float (real), and real is embedded in complex.
It is elegant to embed bool in int, but to me it screams C. To me, it makes more sense to use an int if you want an int, and to reserve boolean for logic. From an elegance/usefulness standpoint, maybe bool should evaluate to 0 and 1. But IMHO, it would eliminate some gotchas and improve readability if it didn't. -Jordan Greenberg, not a Py-Dev, just an interested luser^H^H^Hrker.

Jordan Greenberg <jordangreenberg@gmail.com> wrote:
Guido van Rossum wrote:
How would this change be helpful? I'm utterly mystified by these suggestions that bool would be more useful if it didn't behave like an int in arithmetic.
I don't think anyones really saying it would be more useful, it obviously wouldn't, since like Greg said, it wouldn't work in mapping access or set membership like it does now. I think it would be more readable though, since thinks like this:
True in set([1]) True
or that 5+True is equal to 6 aren't necessarily obvious to someone who doesn't know that True evaluates to 1.
Maybe, but 30-some years of C semantics and another 15 years of Python semantics die hard. a==b for builtin types used to return 1 or 0, now they return True or False. Changing such semantics because some users haven't ever used C or older Pythons would be a bit like changing 'def' to 'fcn' because some users have never used 'def' to define a function. Learn the semantic and move on.
It is elegant to embed bool in int, but to me it screams C. To me, it makes more sense to use an int if you want an int, and to reserve boolean for logic.
You say "screams C" as if it were necessarily a bad thing. Certainly C isn't a perfect language (which is why I use Python), but there are many reasons why I (and others) use (or not) C, but I can just about guarantee you that the semantics of booleans in C *help* rather than hurt its adoption.
From an elegance/usefulness standpoint, maybe bool should evaluate to 0 and 1. But IMHO, it would eliminate some gotchas and improve readability if it didn't.
You are, of course, entitled to your opinion. From what I understand, there is perhaps one major "gotcha" in the current semantics: bool(str(<obj>)) isn't correct for anything except for '' and u''. Then again, that isn't a guarantee with str or bool (or list, tuple, dict, deque, set, etc.) - Josiah

Neal> Except, all the numeric types do, including int, float, and Neal> complex. But not bool. The fact that bool is a subclass of int is more historic than necessary. If not for Python's long usage of 0 and 1 to be the canonical False and True, I suspect that bool might have been implemented as a new standalone type. Skip

Neal Becker writes:
Well consider this:
str (4) '4' int(str (4)) 4 str (False) 'False'
bool(str(False)) True
Doesn't this seem a bit inconsisent?
The former case is a *conversion* from an expression that *does not* have an interpretation in a numerical context to an integer. The latter case is a *canonicalization* from an expression that *does* have an interpretation in a boolean context to the equivalent boolean constant. I don't have a problem with that. YMMV.

Neal Becker schrieb:
Doesn't this seem a bit inconsisent?
Please don't ask such questions. Instead, formulate them as "I would have expected the result to be X instead. Why is the result Y?" (if that is actually the question you meant to ask) IOW, what does it help you if somebody answers "yes" to your question? Regards, Martin
participants (14)
-
"Martin v. Löwis"
-
Ben Wing
-
Georg Brandl
-
Greg Ewing
-
Guido van Rossum
-
Jonathan Lange
-
Jordan Greenberg
-
Josiah Carlson
-
Larry Hastings
-
Mike Klaas
-
Neal Becker
-
Ron Adam
-
skip@pobox.com
-
Stephen J. Turnbull