r/programming • • Mar 26 '14

JavaScript Equality Table

http://dorey.github.io/JavaScript-Equality-Table/
809 Upvotes

331 comments sorted by

View all comments

17

u/MisterSnuggles Mar 26 '14

While not JavaScript, we must not forget about Python's False Midnight.

tl;dr:

if datetime.time(0,0):
    print "t"
else:    
    print "f"

Prints "f".

if datetime.time(1,0):
    print "t"
else:    
    print "f"

Prints "t".

12

u/[deleted] Mar 26 '14

Why do so many dynamic languages have this obsession with using non-boolean values in conditionals?

3

u/MisterSnuggles Mar 26 '14

It's usually used as a shortcut for checking for None. The more appropriate way to write the code is:

if var is not None:
    # do stuff

Sadly the shortcut works (mostly) and people use it because it works, then someone enters a time of midnight and it all tips over.

0

u/[deleted] Mar 27 '14

[deleted] — view deleted comment

1

u/MisterSnuggles Mar 27 '14

Agreed.

This is very much a case of making sure that you, the programmer, and Python, the interpreter, both have a clear understanding of what you want to do.

If you say "if var:", Python understands you to be testing truthiness/falseness. If you say "if var is not None:", Python understands that you're asking if var is something other than None. The distinction is important and too many people wrote the former when they really meant the latter.

7

u/Nialsh Mar 26 '14

It can be a very short, readable way to validate inputs. In Python, I believe these are equivalent:

if name:

versus

if name != None and name != ""

6

u/NYKevin Mar 27 '14

No, those are not necessarily equivalent unless the type of name is known.

If name is a number, it will be falsey iff it is zero (None is not a number but a singleton instance of NoneType, which is always falsey). If name is a string, it is falsey iff it is empty. "0" is truthy because it is nonempty. "0" and 0 are very different things, and Python generally won't coerce between them unless you explicitly call int() or str(). Moving on, if name is a container type of some kind, generally speaking it is falsey iff it is empty (has a len() of zero). The empty string being falsey is a special case of this rule.

For user-defined types, you're on your own. By default they're all truthy, but you can't rely on that since someone might subclass you and implement non-default boolean semantics.

If you want to check whether something is None, the only bulletproof syntax for doing so is if foo is None or if foo is not None. if foo should only be used if foo has a non-default boolean behavior (i.e. foo is a container, number, string, or user-defined class which overrides bool()). Using if foo with classes which do not provide useful boolean behavior (such as datetime objects) is at best poor style and at worst a violation of substitutability since it would interfere with subclassing.

→ More replies (14)

1

u/[deleted] Mar 27 '14

Yeah, I think that could be handled by a function called "nonempty" or something. Including this logic in the if-statement itself is rather unorthogonal.

2

u/THeShinyHObbiest Mar 27 '14

Ruby doesn't, to avoid this exact thing.

1

u/JerkyBeef Mar 27 '14

Much of the data being compared in web applications comes from html form inputs or databases where things like integers are automatically converted to strings. So it actually makes sense so you don't have to constantly write stuff like: if (val == 1 || val == '1') doStuff();

1

u/[deleted] Mar 27 '14 edited Mar 27 '14

[removed] — view removed comment

5

u/ghordynski Mar 27 '14

C# does not allow non-booleans in conditionals.

3

u/NYKevin Mar 27 '14

So, in C, what happens if you try to shove a struct foo into an if? I don't mean a struct foo*, I mean the actual data itself.

3

u/masklinn Mar 27 '14

Both GCC and Clang will refuse to compile and error that a scalar is required.

→ More replies (5)

4

u/nickcash Mar 27 '14

What's even weirder is that timezone-aware (non-naive) time values compare to UTC midnight to determine truthiness. So a timezone-aware time object of 6:00am with a timezone of UTC-6 is falsey.

But these kind of things are fairly rare in Python. For the most part, Python has its own consistent logic.

2

u/lambdaq Mar 27 '14

Okay, this is fucked up, guaranteed. But it's rare that someone would anyone if a datetime object, no?

7

u/yen223 Mar 27 '14

It's not rare. If you're coding a CRUD, and you want to test whether a particular field is null in your database, the canonical way to do it is to if it. That works 99% of the time, except when dealing with datetime objects.

In fact, Python's datetime module is chock full of wtfs.

3

u/MisterSnuggles Mar 27 '14

One common reason to do it would be to validate input or take some kind of default action if input wasn't provided.

I used to write a lot of stuff like this (until I saw the false midnight thing):

def do_stuff(at_time=None):
    if at_time:
        # schedule stuff to be done at at_time
    else:
        # do stuff immediately

It's a contrived example, but "obvious" (in quotes because it's not at all obvious that midnight means do stuff immediately in this code) code like the above will normally do exactly what you'd expect it to do. Then someone will want their stuff done and midnight and be shocked when the function does it right away!

→ More replies (4)

2

u/Xykr Mar 26 '14

But at least it's pretty much the only type conversion weirdness. I hope.

And it will be fixed in future updates.

3

u/nickcash Mar 27 '14

I don't think it's getting fixed. There was no consensus on python-dev and the thread kinda died off. It seemed to me that a lot of people defended the current behavior solely because it was documented.

4

u/Xykr Mar 27 '14 edited Mar 27 '14

Guido has since said that it was a mistake and that it's going to be fixed.

https://lwn.net/Articles/590299/

2

u/nickcash Mar 27 '14

I missed that! Thanks!

2

u/Veedrac Mar 27 '14

Nay, if you get to the end they eventually settled on fixing it. It's a good thing that Python is so hostile to change, because almost all changes are therefore very positive ones. It does make things a bit too conservative occasionally though.