guido: I'll let this short and sweet PEP speak for itself. |
guido: This PEP proposes the introduction of a new built-in type, bool, with two constants, False and True. |
aahz: +1000 ;-) |
martin: I would prefer these constants to be named "true" and "false", respectively. |
guido: But all other built-in constants have an initial capital letter: None, NotImplemented, Ellipsis, ... |
jason: True. |
martin: That certainly doesn't apply generally to all of Python: sys.version, sys.byteorder, sys.platform, sys.maxunicode, |
david.abrahams: Don't you think using "true" in place of "False" and "false" in place of "True" is bound to cause a little controversy <0.7wink>? |
guido: Most languages eventually grow a Boolean type; even C99 has one. |
mal: +1. |
guido: __str__ = __repr__ |
mal: I don't like this: it will break too much code since there are already two singletons Py_True and Py_False available |
guido: But this is the whole point of introducing a new type rather than simply defining True as 1 and False as 0! |
mal: That's not how I read it: making bool a type would allow type checks to be done and this is a *much* more important feature |
guido: Depending on your POV, yes. |
skip: Guido> Don't databases have a separate Boolean type? |
skip: Skip> So do, some don't.... |
guido: False = bool(0, _create=1) True = bool(1, |
mal: Please adjust Py_True and Py_False (at C level) to be identical to these constants. |
guido: Yes, that was the intention. |
guido: Because the repr() or str() of a bool value is different from an int value, some code (e.g. doctest-based unit tests) may fail. |
mal: Please, no ! |
guido: Agreed -- I just mentioned it as a possibility if we find too much problems due to the new repr() and str(). |
david.abrahams: Do you propose to change the type of "x == y" et. al. from int --> bool? Sounds good to me. |
guido: Yes. |
guido: Hm, assert is the wrong thing though, since it's optimized away in -O mode. |
david.abrahams: Ick. Not that I run my doctests in -0 mode, though. |
tim.one: If you want x-version doctests, |
aahz: One question: do True/False behave like None, particularly WRT "is"? |
guido: That depends on what the meaning of "is" is. |
skip: >> One question: do True/False behave like None, particularly WRT "is"? |
mal: Ideal would be to make bool a subtype of int and True and False two singletons created from 1 and 0 having the bool |
guido: That's what I am proposing. |
mal: Add boolean support to the array module so that it becomes possible to create arrays of bits. |
guido: That's an entirely separate issue, and would require major hackery to the array module |
skip: Hmmm... A boolean type can only take on two values. I presume you will expose True and False through builtins. |
guido: Yes. |
guido: __new__ must exist in order to support writing |
mal: There are many situations when doing RPC or interfacing with other systems such as databases where a type check for |
guido: Agreed, this is a nice additional advantage. |
mal: That's the main argument for adding a boolean *type* to the language. We already have the singletons... |
guido: In C, not in Python! |
mal: Sure we do: |
mal: Currently, |
guido: That's a good question. Don't databases have a separate Boolean type? Is there really code out that relies on this? |
mal: Yes and currently it is encouraged to use Py_True and Py_False on DB module output and the truth test on DB module |
mal: mxODBC in SQL binding mode. |
mal: Right. |
mal: There's also another issue here: "True" and "False" are English words, "0" and "1" are language neutral. |
guido: Methinks you are getting desperate for arguments here. :-) Or should we also remove "if" from the language? |
mal: No. The point is that printing truth values up to now has always resulted in '0' or '1'. |
guido: An application that prints the digits 0 or 1 to mean true or false doesn't sound very user-friendly to me either. |
mal: The problem is that the boolean output may not have been intended by the programmer. |
guido: In the long run, you'll thank me for this. |
paul: Guido said not to "mix up" the question of bit arrays with the bool proposal, but really, they *are* mixed up. |
aahz: There's nothing wrong with submitting a PEP that's dependent on another PEP. It's just a Bad Idea to stick too much into a single PEP. |
guido: I dunno about Numeric, |
guido: I made bool a subclass of int to minimize this danger, but I don't know whether Numeric uses PyInt_Check() or not. |
paul: In short, they are mixed up in the sense that this proposed intellectual nicety will cause us Nummies a lot of grief. |
guido: But let's not worry about pain we don't know that we'll really be experiencing. I like to look at things from the bright side. |
paul: BTW: There is quite a bit of pent-up demand in the Numeric community for bit arrays. |
guido: Same for the Python array module. |
guido: I can provide a real implementation next week, and we should have plenty of time to find out how much it breaks. |
mal: Perhaps you could clarify the need for these new __str__ and __repr__ values ?! |
wurmy: This may be a minor issue, |
skip: Hans> This may be a minor issue, |
wurmy: assuming that booleans cannot be added to ints. |
guido: Re-read the PEP. bool subclasses int. 28 + True equals 29. |
wurmy: I'm not sure if there's a lot of code out there that actually uses these numerical values. I occasionally use it, though... |
akuchlin: Hmm... I wonder if this related idiom is common? |
skip: Hans> assuming that booleans cannot be added to ints. |
martin: Under the proposal, this assumption is wrong. bool is defined as a subtype of int; 28+True is 29. |
skip: I don't think this will be a problem. Guido's proposal is for bool to be a subclass of int. |
neal: This gave me an idea that in general it might be useful to try to address the ways that adding a new feature might break existing code. |
mal: This works just fine with Py_True and Py_False, since DBs know that 1 and 0 are true and false. |
guido: OK, so you may have to change one line in one module. |
mal: Nope. I'll have to add a new handler which detects the bool type and converts it to 1 or 0 resp. |
mal: I'd be happy with repr(True) giving me 'True', but not str(True). |
guido: It just seems to make more sense if booleans print as True and False. |
mal: Good. |
guido: This is now in the PEP as an option. |
mal: (It's not like I'm running out of arguments :-) |
guido: We'll see. |
paul: FYI: Numeric makes arrays of anything. |
DavidA: Current Rationale for PEP 285: |
DavidA: I'd like to get a clearer understanding of the rationale of adding a new type which would become commonly used, |
guido: Yeah, there's always a lot of things that must be changed... |
skip: Guido, |
tim.one: That's what drove C99 to standardize a bool type. |
DavidA: While I've often wanted a boolean |
guido: It is commonly seen as a small wart. |
DavidA: That's easy. |
guido: If PEP 285 is withdrawn, I could do a milder version. |
DavidA: That is a real issue except that it seems to have been solved relatively well by all of the language bindings so far. |
guido: I didn't invent this argument; Marc-Andre thought it would be helpful. I see it as a mild argument at most. |
DavidA: Agreed. I also agree w/ the mildness of it. |
DavidA: This is intriguing. |
guido: When showing people comparison operators etc. |
DavidA: 4) Booleans lead quickly to the 'memory savings' notions of packed arrays of bits, |
guido: This doesn't interest me much. |
DavidA: All in all, I'm neither for nor against at this point, but I think the rationale for the change needs further elaboration. |
guido: Wait till you've seen the implementation. |
guido: >>> a = 13 >>> b = 12 |
DavidA: vs. |
guido: it would require one millisecond less thinking. |
mal: and then they do: |
guido: >>> cmp(a, |
DavidA: Which really seems to be the key issue, both as a positive (your argument) and as a negative (MAL's posts). |
guido: It certainly is what motivates me. |
mal: The effort required to do this is not the argument, it's the fact that you are trying to break working code |
guido: OK, now we're talking. You want more motivation. See my response to David Ascher; I'm going to add all that to the PEP online too. |
mal: >>> True * 10 True |
guido: What has logic got to do with this? |
mal: Booleans are by nature truth values. |
guido: So you're reversing your position. First (see above) you were pleading that True*10 should yield True. |
mal: No, I'm just giving evidence of what mixing booleans with bits can lead to. |
mal: However, this would break even more code... |
guido: I never said otherwise. It behaves exactly like int except for those operations where the PEP specifies something different. |
mal: Exactly; which is why I don't understand the move to override __str__ with something which doesn't have anything |
guido: Probably because we have a different intuition on how str() is used. For me, it's mostly used as an output conversion. |
mal: Right. |
DavidA: I wonder if the str()/repr() distinction or % formatting codes could help break the logjam. Probably not. |
guido: Marc-Andre has suggested that, and I'm willing to give it a try if it's needed to save the PEP. |
DavidA: I'm still not convinced that the disease is worth the cure, but I'm open-minded =). |
guido: :-) |
david.abrahams: The big reason I was excited about bool in C++ when we got it was that I knew I'd be able to do this, |
guido: Now let's you and I go decide on the Python track and tutorials for OSCON 2002... |
jacobs: I know the deadlines was a week ago, but I just found out (about 10 minutes ago) that I will be in the country for OSCON 2002. |
pedroni: Hi, |
pedroni: Question: what will happen with all the return 1 or return 0 etc in the std lib and in user code and in the inline doc |
guido: Ideally they would have to be changed into True and False, but there's no hurry -- 0 and 1 will continue to be valid as truth values too. |
pedroni: which unchanged will define a bool vs int function.) |
guido: A job for PyChecker! |
pedroni: There are function in the std lib that return 1 on success, 0 on failure. |
guido: I doubt there are any functions returning 0 for success and -1 for failure, but if there are, they should not be changed. |
guido: Another reason to introduce a Boolean type. |
pedroni: Then there are really predicate function/methods, they should probably be changed? |
guido: Yes. |
guido: Yes, it will take time before everything is converted. That's why we must be careful to decide if we really want this. |
skip: I'm kinda curious. I understand all the arguments, but they've been around for a long time. |
guido: Well, the subclassing from int solution is new in 2.2. |
tim.one: It's obvious to me. I sent a "PEP Parade" message last night, stating in part that Guido wanted to keep new features out of the core for 2.3. |
pedroni: From: Guido van Rossum <guido@python.org> |
gsw: I didn't want to jump on the bandwagon, but... |
gsw: def __cmp__(self,other): return int.__cmp__(self,bool(other)) |
guido: Absolutely not. I want True == 2 to be False. |
DavidA: Intersesting. |
DavidA: but: 2 == True would be False |
guido: Just as in C99 (the new updated C standard, not yet in actual use). |
DavidA: Once again, casting, coercion, comparisons and truth value rear their fuzzy heads. |
guido: For the first time, we'll have a standard way to cast an arbitrary value to a normalized truth value. |
barry: That's a huge benefit I hadn't thought of. I use that idiom often because it's a cheap substitute for the lack of a ?: statement. |
tim.one: Then you won't get hosed by -O (as an assert would do). |
david.abrahams: ...I guess I can see why you're really intending that |
david.abrahams: Yes. |
mal: I think in summary, the confusion we have run into here is caused by Python's use of bits to represent booleans. |
guido: I don't understand this. The way I see it, current Python doesn't use bits for Booleans. |
mal: Bits are 1 and 0. Booleans are True and False. |
guido: Yes, forced by backwards compatibility. |
mal: Heck, it's only one method we're argueing about here. |
guido: Maybe because at the start it wasn't clear that that is your only *real* objection, and you brought so many other arguments into play? |
mal: You started this game and asked for these many arguments :-) |
guido: OK, I've played enough. |
guido: I've spent an evening hacking. |
pedroni: http://sourceforge.net/tracker/?func=detail&atid=305470&aid=528022&group_id=547 0 |
mal: Could be... I don't like it when things are broken on purpose just to have an interactive session return "nice" output. |
guido: I thought about this last night, and realized that you shouldn't be allowed to subclass bool at all! |
david.abrahams: This sure rubs all my expectations for a bool the wrong way, though. |
tim.one: It has much more to do with expectations for what "and" and "or" do. |
david.abrahams: Yes, I realize what's actually going on (and/or are Lisp-y), but as I said, it rubs my expectations for expressions with bool the wrong way. |
david.abrahams: That mixing was your suggestion, |
tim.one: Of course: it solved your problem. That you went on to whine about it isn't really my doing <wink>. |
tim.one: Na, |
guido: Anyway, in a brand new language the latter might be a good idea, but since we're trying to evolve Python without breaking |
mal: Right, but please don't try to add some booleaness to bits. |
guido: >>> isinstance(1, |
pedroni: My 2cts. |
mal: This is not different from printing other objects: |
guido: So I need someone else to chime in with additional evidence that str(True) should be '1', not 'True'. |
mal: I was also the only one that had objections when nested scopes were first proposed by Jeremy on this list... |
gmcm: It hasn't helped that the argument has contained a whole lot of red herrings. |
mal: While I don't agree that the arguments I included in the thread were red herrings, |
mal: My only objection is overriding the __str__ method. Everything else is just fine. |
guido: Good. |
mal: You don't have a boolean type in the sense of algebra, |
guido: Agreed. There's only so much we can do without applying the time machine to 12 years of code developed by 100,000s of people. |
mal: Hmm, perhaps you should name the type "truth" or "truthvalue" rather than boolean. |
guido: Yuck. It's called bool (or Boolean) everywhere else, even when the semantics are defined to be just different names for 0 and 1. |
mal: There must be other ways to satisfy your requirements and mine. |
guido: We'll see. I'm flexible. |
pedroni: Probably non-sense: |
pedroni: should be true. |
gmcm: You're right. |
gmcm: If there were any proposal for and / or to return booleans, I'd scream bloody murder, |