Fun with none

by rohit on July 16, 2009

(If you are in a hurry, here is the fun part. ;)

A few days ago, I was working with a nullable field, which wasn’t behaving as I expected. So I started a shell, and see how nulls compare.

In [1]: None
In [2]: None > 10
Out[2]: False
In [3]: None < 10
Out[3]: True
In [4]: None == None
Out[4]: True

Funny, not as I expected. (Why is None < 10 True. I thought it would be either False or None or cause an Error?)

So python is obviously broken, next steps, see the same thing in some other language. Lets try some other language, Javascript maybe?

//#Javascript
>>> null
null
>>> null == 10
false
>>> null > 10
false
>>> null < 10
true
>>> null == null
true

Ruby?

irb(main):001:0> nil
=> nil
irb(main):002:0> nil > 10
NoMethodError: undefined method &gt;' for nil:NilClass
  from (irb):2
  from :0
irb(main):003:0&gt; 10 &gt; nil
ArgumentError: comparison of Fixnum with nil failed
  from (irb):3:in>'
  from (irb):3
  from :0
irb(main):004:0> 10 < nil
ArgumentError: comparison of Fixnum with nil failed
  from (irb):4:in ` 10 == nil
=> false
So, this piqued my curiosity and without further ado, here is how None/nil/null/Nothing behave in fifteen different languages. You would assume they would have sorted something this basic out by now. :)

Comparision of how null behaves in different languages for

  • null > 10
  • null < 10
  • null == 10
  • null == null
Null > 10 Null < 10 Null == null 10 == 10 Null == 10 names Link
Python FALSE TRUE TRUE TRUE FALSE None http://gist.github.com/147892
Ruby Error Error TRUE TRUE FALSE nil http://gist.github.com/147894
Lua Error Error TRUE TRUE FALSE nil http://gist.github.com/147906
Javascript FALSE TRUE TRUE TRUE FALSE null http://gist.github.com/147909
Mysql null null null TRUE null null http://gist.github.com/147921
Psql null null null TRUE null null http://gist.github.com/147915
Sqlite null null null TRUE null null http://gist.github.com/147919
Haskell Error Error TRUE TRUE Error Nothing http://gist.github.com/147953
Clojure Error Error Error TRUE Error nil http://gist.github.com/147958
Java Error Error TRUE TRUE Error null http://gist.github.com/147932
Groovy FALSE TRUE TRUE TRUE FALSE null http://gist.github.com/147936
Perl Error Error Error TRUE Error undef http://gist.github.com/147925
Scala Error Error TRUE TRUE FALSE null http://gist.github.com/147923
Jython FALSE TRUE TRUE TRUE FALSE None http://gist.github.com/147914
Php null TRUE TRUE TRUE null null http://gist.github.com/147899

All these are high level languages, and with exception of Java/Haskell/Sql are dynamically typed, so why is there this much difference in how None/null/nil as a type is handled?


As you can tell, I am very new to some of these languages, so if I have got your favorite language wrong. Please let me know in the comments and I will fix it.

Related posts:

  1. The Rails and Django models layer Rosseta stone

49 Comments 6 Tweets 1 Comment

{ 68 comments… read them below or add one }

1 albinofrenchy July 16, 2009 at 12:56 pm

When we are talking about something like truth values though, it is an odd comparison. There is no direct mapping; and that is to the credit of the language.

This comment was originally posted on Reddit

2 albinofrenchy July 16, 2009 at 1:02 pm

> are converted to integers for the comparison by a set of **arbitrary** rules. FTFY

This comment was originally posted on Reddit

3 rabidcow July 16, 2009 at 1:06 pm

> as shown by Scala, you can have Maybe and also null in the same language. Bottom (aka `undefined`) exists independently of null in every Turing-complete language with null. For example: int bottom() { return bottom(); }

This comment was originally posted on Reddit

4 master_troll July 16, 2009 at 1:18 pm

> I can’t think of any example of where you would use undefined in haskell the way one would use null in another language. It is very useful to generate random runtime errors á la C/C++/Java

This comment was originally posted on Reddit

5 albinofrenchy July 16, 2009 at 1:24 pm

> Hint: you can’t! I can’t think of any example of where you would use undefined in haskell the way one would use null in another language. When an invalid program state is hit. Head on an empty list for instance. > As an example, how would you write a linked list in haskell using undefined to terminate it, like you would use null in, say, java? I also wouldn’t use ‘Maybe’. ‘data Linked a = LNode a (Linked a) | TNode a’ Part of the appeal for me of haskell is it doesn’t let you use a null reference as control flow. ‘undefined’ is the only thing you can make something that isn’t of its static type, and that is a toxic object.

This comment was originally posted on Reddit

6 tejoka July 16, 2009 at 1:36 pm

> When an invalid program state is hit. Head on an empty list for instance. But that’s not using it the same as you would null in a Java program. Using undefined here is more the equivalent of throwing an exception. > I also wouldn’t use ‘Maybe’. I originally called it a contrived example, but I didn’t think it was worth worrying about whether it was contrived or not. The point is that Nothin is the closest thing to null, and undefined is completely different. (and your definition should probably have LNil not TNode a, otherwise you can’t have an empty list! ;) )

This comment was originally posted on Reddit

7 keithjr July 16, 2009 at 1:47 pm

The Perl line is not really correct. The linked code doesn’t generate errors, it generates warnings. These go away if you run without "use strict; use warnings;" And either way, the results of all the comparisons or assignments appear to be "undef," which makes sense.

This comment was originally posted on Reddit

9 logan_capaldo July 16, 2009 at 3:08 pm

This I know. But bottom is the value closest to a null in Haskell, as it inhabits every type, like null does in those other languages (save Java’s primitives). Nothing is not much like null at all. Bottom, arguably is.

This comment was originally posted on Reddit

10 brool July 16, 2009 at 3:13 pm

In Python, say you have a list of objects: [o, o1, o2, o3] but it’s possible for some objects to be missing: [o, None, o2, o3]. In Haskell you would certainly use Maybe instead of undefined.

This comment was originally posted on Reddit

11 bobbyi July 16, 2009 at 3:42 pm

You don’t need the ability to sort heterogeneous lists in order to compare sets; you just need the objects to support being compared for equality.

This comment was originally posted on Reddit

12 rabidcow July 16, 2009 at 5:13 pm

> But bottom is the value closest to a null in Haskell, as it inhabits every type, like null does in those other languages (save Java’s primitives). Yeah, that’s a defining characteristic of null, but so is the ability to distinguish it from all other values at runtime.

This comment was originally posted on Reddit

13 snarfy July 16, 2009 at 6:07 pm

Considering mathematical purity, which way is the correct way? IMO it is the SQL way. That also means the only way to compare if something is null is by using a new operator, e.g. an IsNull() method / operator. It would be intrinsic to the language since you can’t really implement it using the language itself.

This comment was originally posted on Reddit

14 Cyrius July 16, 2009 at 6:39 pm

>Glad they cleared up all the confusion over (10 == 10). Apparently it returns true. There was some question about it in PHP.

This comment was originally posted on Reddit

15 logan_capaldo July 16, 2009 at 10:25 pm

Fair point. Bottom isn’t null, but neither is Nothing.

This comment was originally posted on Reddit

16 logan_capaldo July 16, 2009 at 10:34 pm

As rabidcow points out, http://www.reddit.com/r/programming/comments/91p9c/fun_with_none_truth_value_of_none_or_null_in/c0b598k , null has at least two defining characteristics, a) it inhabits every type, and b) you can distinguish from all other values at runtime. `undefined` has a but not b, Nothing does not have a, and it doesn’t really have b, because code that attempts to do b will fail to compile (and not be a program). You might use Maybe t, in places where in other languages you would just use t in conjunction with null, but just because they have some intersecting use cases does not make the constructs have the same semantics. Originally I would argue "undefined is closer to null than Nothing", now I would say "Haskell doesn’t have null, that whole table should be NA".

This comment was originally posted on Reddit

17 divbyzero July 20, 2009 at 3:23 am

It’s true you only *need* equality, but without some ordering the best you’ll do is quadratic time O(nm) versus O(n log(n)) with sorting. That starts to suck pretty fast.

This comment was originally posted on Reddit

Leave a Comment

Additional comments powered by BackType

Previous post:

Next post: