Live data from Hacker News

Please reconsider the Boolean evaluation of midnight

mail.python.org

181–190 of 218 posts

Re: Please reconsider the Boolean evaluation of midnight

#182
post #176

INADA Naoki's argument [1] is succinct and insightful. I feel zero value of non abelian group should not mean False in bool context. () + () == () "" + "" == "" 0 + 0 == 0 timedelta() + timedelta() == timedelta() time() + time() => TypeError [1] https://mail.python.org/pipermail/python-ideas/2014-March/02...

What do those code samples have anything to do with abelian groups? Abelian groups are those whose group operator is commutative, i.e. a + b = b + a for all a and b. The code examples seem to be referring to the existence of an identity element, which is necessary for all groups.

I think what he was saying was: * You should use + only for operations that form an abelian group across the domain * In those cases, it makes sense for the identity to be false.

The truth is, time doesn't have a sensible addition/combination operator, never mind an identity and inverse, so it isn't even a group.

Re: Please reconsider the Boolean evaluation of midnight

#183
post #176

INADA Naoki's argument [1] is succinct and insightful. I feel zero value of non abelian group should not mean False in bool context. () + () == () "" + "" == "" 0 + 0 == 0 timedelta() + timedelta() == timedelta() time() + time() => TypeError [1] https://mail.python.org/pipermail/python-ideas/2014-March/02...

What do those code samples have anything to do with abelian groups? Abelian groups are those whose group operator is commutative, i.e. a + b = b + a for all a and b. The code examples seem to be referring to the existence of an identity element, which is necessary for all groups.

Yeah, I was trying to figure that out too. They seem to care about closure and identity, but most of the examples have operators that trivially break an Abelian group's commutative requirement.

Re: Please reconsider the Boolean evaluation of midnight

#185
post #157
post #154

Earlier quoted context omitted.

{1: ["A", "B"]}?

Okay, then what about {1: "A"} + {} Should that return {1: ["A"]}? In which case {} is no longer a zero value. What about {1: "A"} + {} + {1: "B", 2: "Z"} + {1: "C"} + {} In any case, your suggestion would break all existing code. Based on all the StackOverflow and python-list questions, most people expect one or the other value, and few want the two-element list containing both. (And why a list instead of a tuple?)…

This could be interesting. One would have to define what hash math should mean. Personally, I would expect (based on my naive assumptions here) that:

    {1: "A"} + {} == {1: "A"}
but

    {1: "A"} + {} + {1: "B", 2: "Z"} + {1: "C"} + {}
should reduce to:

    {1: ("A" + "B" + "C"), 2: "Z"}
Whether you can add "A", "B", and "C" would depend on string functions (could be "ABC" or raise an exception that these cannot be added for example).

Re: Please reconsider the Boolean evaluation of midnight

#186

Earlier quoted context omitted.

It's undocummented, and very complex to use. That mail does not even have sufficient information to understand how to use this "feature". I hightly doubt anybody uses it outside of the datetime codebase. I never saw Linus complaining about changing undocummented and not used behaviour.

It is documented. That's the strongest argument against changing it: it's a documented piece of user-facing behavior. The python developers are changing it anyways because they're practical people who have decided it is more likely that people wrote bugs into their code, than that they wrote code that depended correctly on the falsiness of UTC midnight.

This is true, but if it is documented it is still sufficiently oddball to be useless. Consider:

    Midnight UTC, timezone EST:  True
    Midnight UTC, timezone CET:  False
    Midnight UTC, timezone CST:  True
    Midnight UTC, timezone WIT:  False
    Midnight UTC, timezone PST:  True
Now the problem here is that it may well be documented but it is in fact unsafe to rely on in any context. The behavior is thus irretrievably broken, documented or not. It isn't even expert-friendly. The behavior, documented or not, is irretrievably broken. After all timezones west of GMT will never have false times.

If there is a use case for this behavior, I sure can't see it. Unless you like bugs appearing when you change timezones.

Re: Please reconsider the Boolean evaluation of midnight

#187
post #2

I just got bit by this a few days ago. I was creating an event scheduling system that uses either repeating entries with a datetime.time, or one time entries with a datetime.datetime. I had code that said "if start_time" to see which it was, and discovered later that midnight evaluates to false. It's not the best idea.

What's actually interesting if you dig into the discussion is that the actual behavior depends on your timezone.

Basically from UTC east to the IDL, it behaves as you describe it. Anything west, it evaluates to true as long as it is set and there is a timezone offset. This is because once you are at a negative offset, you subtract and get a higher number so it will never evaluate to false with a negative offset.

Basically this current behavior is useless for anything I can imagine. You can't use it to check for midnight UTC. You can't use it to check for whether it is set. You can probably use to check for midnight with no timezone but add a timezone and now your handling is messy.

This is why contracts need to be sanely written from a code contract point ahead of time. This was apparently a developer describing how his code worked and later calling it a contract, which is a very bad thing :-D

Re: Please reconsider the Boolean evaluation of midnight

#188
post #150

INADA Naoki's argument [1] is succinct and insightful. I feel zero value of non abelian group should not mean False in bool context. () + () == () "" + "" == "" 0 + 0 == 0 timedelta() + timedelta() == timedelta() time() + time() => TypeError [1] https://mail.python.org/pipermail/python-ideas/2014-March/02...

If that were true, it would mean that dict should not support bool: >>> {} + {} Traceback (most recent call last): File " ", line 1, in TypeError: unsupported operand type(s) for +: 'dict' and 'dict' >>> bool({}) False Since I find bool(a_dict) to be very useful, and the lack of a_dict+b_dict to be reasonable (precisely because it's non-abelian!), I conclude that logic is cute, but not that relevant. Those who think…

{1:"AB"}

That's how it usually works with functions.

Re: Please reconsider the Boolean evaluation of midnight

#189
post #188
post #150

Earlier quoted context omitted.

If that were true, it would mean that dict should not support bool: >>> {} + {} Traceback (most recent call last): File " ", line 1, in TypeError: unsupported operand type(s) for +: 'dict' and 'dict' >>> bool({}) False Since I find bool(a_dict) to be very useful, and the lack of a_dict+b_dict to be reasonable (precisely because it's non-abelian!), I conclude that logic is cute, but not that relevant. Those who think…

{1:"AB"} That's how it usually works with functions.

If you want that, try the Counter class:

    >>> from collections import Counter
    >>> Counter({1: "a"}) + Counter({1: "b"})
    Counter({1: 'ab'})
But Python dictionaries won't support '+' because of the ambiguity. This goes back to 1994: http://ftp.ntua.gr/mirror/python/search/hypermail/python-199...

    Lance Ellinghouse:
    why can't I add dictionaries like I can other objects?
    ...
    if a and b both had the same keys, then I think b should override
    the keys in a.
and Kenneth Manheimer posted a dict-like implementation in http://ftp.ntua.gr/mirror/python/search/hypermail/python-199... which also has the replacement behavior.

Guido responded in http://ftp.ntua.gr/mirror/python/search/hypermail/python-199... saying that he could think of no reason to prefer replacement over keep behavior.

In my own early Python code, I sometimes used + when I wanted an update semantic, so I can confirm that your expectations aren't universal.

And that's what this comes down to - is bool(time(0, 0))==False the generally expected behavior (which is a higher threshold than reasonable behavior)? What are the likely errors? Do the advantages outweigh the disadvantages?

That's why an argument about the zero element is only somewhat relevant - most programmers aren't mathematicians, and practicality beats purity.

Re: Please reconsider the Boolean evaluation of midnight

#190

INADA Naoki's argument [1] is succinct and insightful. I feel zero value of non abelian group should not mean False in bool context. () + () == () "" + "" == "" 0 + 0 == 0 timedelta() + timedelta() == timedelta() time() + time() => TypeError [1] https://mail.python.org/pipermail/python-ideas/2014-March/02...

But you can make an equally succinct argument in the opposite direction, namely to treat time values as polar coordinates. Then they indeed form an abelian group:

    a + 0:00 = a
    15:00 + 13:00 = 02:00
    12:00 + 12:00 = 00:00
The examples are for hours only, but you can extend it for minutes too. Showing that time values on a clock forms an abelian group under addition is a textbook example everyone uses when introducing group theory.
Post reply on HN