rohit
Comments
Reactions

Fun with none

By : rohit

(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 `>' for nil:NilClass
  from (irb):2
  from :0
irb(main):003:0> 10 > 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


Can we help you build amazing apps? Contact us today.

Comments

Tony Morris

You have the Scala table wrong. You should be using scala.Option. Scala's null is a Java hangover is better to be thought of as similar to Haskell's undefined.

commmenttor
Py3None 16th July, 2009

Additional info fyi: In Python 3, they have changed the rules to prevent comparisons that don't make sense, so the first two comparisons give Errors.

commmenttor
Troels 16th July, 2009

You also have the php table wrong. It should be:

FALSE, TRUE, TRUE, TRUE ,FALSE

commmenttor
rohit

Troels:

You are right. I got it wrong as I assumes when nothing is printed on the repl, then the value is none. Apparently, this is not the case. http://gist.github.com/148365

commmenttor
rohit

@tonomorris: Thanks. The results of scala with None, which subclasses Option are at http://gist.github.com/148368. I will update the table later.

commmenttor
Troels 16th July, 2009

@rohit: Use var_dump. Like this: http://gist.github.com/148380
When you echo, the value gets coerced to a string.

commmenttor
Logan Capaldo 16th July, 2009

I disagree with the comments with regards to Scala. Rather than using Option for Scala, you should be using undefined for Haskell. Programs that don't compile aren't programs, and the comparision is meaningless. Using undefined in Haskell is a more in the spirit of the "none" values in the other languages.

commmenttor
Michael Peters 16th July, 2009

You're Perl conclusions are wrong. Those things you think are errors are actually just warnings and Perl is returning a blank value (which is "false"). The only one that is erroring is the 3rd one. So the results should be:

FALSE, TRUE, FALSE, TRUE

(some code to help you out - http://gist.github.com/148428)

commmenttor
Captain Obvious 16th July, 2009

I'm not even a Python developer and I can tell you that Python isn't "broken" because (none &lt; 10) is true. It's the same as in PHP: the &lt; comparison requires integer arguments, so none/null is cast as an integer for the comparison. This is what happens in a weakly typed language, it's not "broken" unless you consider weak typing fundamentally evil.

commmenttor
shabda

Captain obvious: Python isn't weakly typed. Python is dynamically but strongly typed.

About null being evaluated to 0, test this on a python console

None -10

Michael Peters:

What is the closest in Perl thing to None in Python. Undef looks like it is for undefined things, which (at least in Python) are different from None.

commmenttor
Grok2

You know, you should first understand what you are doing, before you comment "they would have sorted something this basic out by now". Doing something incorrect with the language feature and claiming that the language doesn't work like you expect doesn't make sense -- see all the comments you are getting about how what you are seeing is wrong....

commmenttor
Cale Gibbard 16th July, 2009

I disagree that undefined in Haskell is anything like the null value in other languages. It's more like an infinite loop or a value which when evaluated causes the entire program to abort immediately (which is very different from null in most of those others).

However, it would be worth noting in the table which of the errors are compile time and which are runtime errors. (The ones for Haskell are type errors which occur at compile time, since there's no instance of Num for Maybe values.)

commmenttor
Lakshman

Just came across this stuff in Javascript:

'' == '0' //false
0 == '' //true
0 == '0' //true
false == 'false' //false
false == '0' //true
false == undefined //false
false == null //false
null == undefined //true
" \t\r\n" == 0 //true

commmenttor

Reactions

uswaretech

http://bit.ly/8awqR New post. How boolean operators work on null in fifteen different languages.

This comment was originally posted on Twitter

adrianb

> So python is obviously broken It doesn’t seem so broken if you think None can be seen as an integer equal to 0 (as per the legacy of C). This can be applied to weak typed languages and C (which has integers as pointers). For Java and strongly typed languages, null is a reference so it cannot be compared to integers (still nothing is broken).

This comment was originally posted on Reddit

spotter

Actually I think it was considered broken and fixed — IIRC should raise an exception in Py3k. Can’t check it now though.

This comment was originally posted on Reddit

Brian

That isn’t the reason. `None < -10` will still give `True`. Instead, it’s because python defines arbitrary but consistent sort orders between different types in order to allow sorting heterogenous lists. eg. if you have a list like: l = [None, 1, "test", 500, None, 213] it may be useful to process this in some consistent order – eg you want all the Nones clumped, all the strings clumped etc. Comparisons between incompatable types will be consistently ordered (so for instance, all strings will be greater than all integers, or vice-versa, but never a situation where string_a < int_a but string_b < int_c.

This comment was originally posted on Reddit

valisystem

> It doesn’t seem so broken if you think None can be seen as an integer equal to 0 (as per the legacy of C) I can’t agree more, but it is still broken. The billion dollars mistake of introducing the idea of "invalid state" into programs, and allowing it, should also means that it cannot be manipulated. Data based stuff like SQL makes it clear. For languages that throws errors, i suspect that it is more a side effect of language design. Hum, i also love the complete non sense of php. Explainable, but completely unacceptable.

This comment was originally posted on Reddit

Brian

Yeah, this has changed: >>> None < 10 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unorderable types: NoneType() < int()

This comment was originally posted on Reddit

programmingjoy

Fun with none. Truth value of None (or null) in different languages. #programming http://bit.ly/OwN8a

This comment was originally posted on Twitter

MacbethIII

Fun with None in different programming languages .. http://bit.ly/mPl8c

This comment was originally posted on Twitter

troelskn

The php table is wrong.

This comment was originally posted on Reddit

roerd

I’m wondering why SQL dialects were included. IIRC SQL’s null represents the empty set so of course queries for elements of the empty set that satisfy certain condiditions will result in the empty set again. Nothing strange about this.

This comment was originally posted on Reddit

masklinn

> I can’t agree more, but it is still broken. Thought not broken anymore, it’s been fixed in Python 3: $ python3.0 Python 3.0.1 (r301:69556, Jul 13 2009, 22:38:33) [GCC 4.0.1 (Apple Inc. build 5493)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> None > 10 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unorderable types: NoneType() > int() >>> None < 10 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unorderable types: NoneType() < int() >>>

This comment was originally posted on Reddit

divbyzero

Sorting heterogeneous list, yuck! After the initial revulsion I was trying to think of a legitimate use but couldn’t find one other than to compare two sets. So glad this is changed for py3k.

This comment was originally posted on Reddit

logan_capaldo

The Haskell code is ludicrous. For an accurate comparison it should be using `undefined`, not `Nothing`. None of that code even type checks (compiles).

This comment was originally posted on Reddit

mccoyn

If I were making a game, I would have a list of objects that need to be updated every round. Some of these would be player-controlled. Some would be AI-controlled and some would only be affected by the physics engine. Each has a different type. Now, in each round, I want everything to be updated in the same order. Otherwise, a player might see an AI-controlled object take two turns at once, or none at all. Worse, some objects might be removed from the list only to be returned later (because the player moves out of the area and updating the far away objects is a waste of time.) Obviously some sorting is required. It doesn’t matter what the sort order is, just that every time I insert an item it is sorted consistently. The Python rule allows me to define a sort order for each type and get a sort order for all types for free.

This comment was originally posted on Reddit

Imagist

Yeah, this is fixed in Python 3.0. Still, I would really like Python to be more strict with its types. For example, I wish that… if None: print("Do something") …and… if []: print("Do something else") …would return errors. Instead, both act like… if False: print("This never runs") In general, I think dynamic typing is A Good Thing. But this highlights the downside of dynamic typing in that a lot of things will simply fail silently. Too often bad programmers will use "if ls" to check "if ls == []" and when "ls" comes in as null, their program doesn’t catch it until later when it’s much harder to see where it went wrong.

This comment was originally posted on Reddit

Leonidas_from_XIV

Ha, and Scheme does not even have a `None`-like type -> issue solved. (Actually, some Schemes expose a `nil` value, like for example Guile)

This comment was originally posted on Reddit

sethg

I assume that’s why the table says "Error". I think it’s fair to say that if you’re writing a program in Haskell and wondering "in Java I would use ‘null’ here, what should I use in Haskell?", the answer is more likely to be "Nothing" than "undefined".

This comment was originally posted on Reddit

sethg

Note that in PostgreSQL, if you ORDER BY a column with null values, the nulls will sort higher than everything else. (I don’t know how other SQL dialects handle this.) In that sense, NULL > 10.

This comment was originally posted on Reddit

Brian

Technically, I don’t think that would require sorting, and even if it did, you could simply implement comparison methods between objects of your types – this wouldn’t be impacted by builtin python types being non-comparable. There are use-cases for arbitrary objects, but they’re not that common, and many are now redundant. For example, a common way to sort on some key used to be to use a decorate/sort/undecorate pattern like this: l = [(obj.foo, obj) for obj in items] # Decorate l.sort() # Sort l=[x[1] for x in l] # Undecorate You’d want this to work for any object with a foo attribute, or whatever your key happened to be (ie. support duck typing). However, if two objects have the same value for foo the comparison continues with the next item in the tuple. You don’t really care about the order here, but wouldn’t want an exception because the two objects were uncomparable. This problem no longer exists though, because methods like sort() have grown a key parameter that sorts **solely** on that key, stably and without requiring the objects themselves to be comparable. There may also be other cases where no such alternative exists, but generally even these are compromised by the fact that you can no longer rely on objects being comparable, due to the existance of types like complex or user defined types throwing exceptions, so you’d need to use another method to do so reliably anyway.

This comment was originally posted on Reddit

logan_capaldo

The table also shows "Error" for runtime exceptions when they occur in other languages. It should at least distinguish between the too, but really, as shown by Scala, you can have Maybe and also null in the same language. Nothing is not a drop in replacement for null, it has very different semantics.

This comment was originally posted on Reddit

Brian

That isn’t related to dynamic typing. There exist static languages with similar behaviour, and dynamic languages which don’t. It’s simply the decision of what should be considered true. Python follows the C (note: static typing) approach of considering a range of things false, specifically: `False`, `0`, `0.0`, empty sequences, or anything else that implements the `__nonzero__` (or __bool__ in python3) method appropriately. >"if ls" to check "if ls == []" Of those, I’d far prefer "if ls". The second requires a specific type, and will fail if `ls` is an empty tuple, or a user defined container type. If you’re going to use explicit comparisons, you should instead use "if len(ls) == 0:" or similar, though personally I like the "empty acts like false" behaviour.

This comment was originally posted on Reddit

rabidcow

Yeah, but you’d also be comparing with `Just 10`, not just `10`.

This comment was originally posted on Reddit

dirtside

What’s unacceptable about it? The > operator requires numeric arguments (integer or float) and non-integer args are converted to integers for the comparison by a set of standard rules. I can see how the argument could be made that being stricter would help, but it’s not exactly that hard to remember that (int)null is 0.

This comment was originally posted on Reddit

popcat

type error please

This comment was originally posted on Reddit

timeshifter

Or "Nothing" in VB… God I hate that language.

This comment was originally posted on Reddit

ImpotentNerdRage

Glad they cleared up all the confusion over (10 == 10). Apparently it returns true.

This comment was originally posted on Reddit

Imagist

>That isn’t related to dynamic typing. It’s true that static languages do something similar, but I think it is related to dynamic typing in that if you don’t know the type of the thing being tested (you never know if ls is a list), it’s much more difficult to predict the behavior of the test. For example in C, testing against "i" has very predictable behavior if "i" is an "int". In Python, however, you can’t say "i is an int" unless you have specifically tested "type(i) == int" (which would defeat the entire time-saving aspect of dynamic typing). I could be a list, a null, a string, or anything else, all of which would have different behaviors. >Of those, I’d far prefer "if ls". The second requires a specific type, and will fail if ls is an empty tuple, or a user defined container type. I guess this is a matter of situation and also preference. Unless I’ve designed the entire function to support multiple types, I would rather have it fail if ls is an empty tuple or a user container type. Maybe I’m taking the idea to the extreme, because tuples are conceptually similar to lists. It’s just that I find it hard to envision a situation where one would want the code to behave the same way if ls == [] or if ls == 0. >If you’re going to use explicit comparisons, you should instead use "if len(ls) == 0:" or similar, Agreed. This is certainly a better solution than the one I posted.

This comment was originally posted on Reddit

bitwize

In Scheme, `’()` (empty list) will not compare numerically to any number, but an expression that evaluates to `’()` will be treated as true if used as the conditional in an `if` or `cond` expression; only the distinguished value `#f` will behave like false. Cue bitching from CL proponents about how the _right thing_ is to make nil act like false in a boolean context.

This comment was originally posted on Reddit

jganetsk

Null is a billion dollar mistake.Scala, Java, and Javascript all have a difference between undefined and null. The author doesn’t go into this detail. He also doesn’t differentiate between a runtime error and a compile-time error.

If you do the same test with Haskell’s undefined, then all the expressions throw a runtime exception.

Haskell and SML really have the approach that has a strong foundation. The inconsistencies across languages are due to them not sharing the same foundation.

This comment was originally posted on Hacker News

j0rd4n

The forgot the line for COBOL- Null > 10 – UNDEFINED OR UNUSABLE HOST VARIABLE "NULL" Null < 10 – UNDEFINED OR UNUSABLE HOST VARIABLE "NULL" Null == null – UNDEFINED OR UNUSABLE HOST VARIABLE "NULL" Null == 10 – UNDEFINED OR UNUSABLE HOST VARIABLE "NULL"

This comment was originally posted on Reddit

j0rd4n

They forgot the line for COBOL: * Null > 10 – UNDEFINED OR UNUSABLE HOST VARIABLE "NULL" * Null < 10 – UNDEFINED OR UNUSABLE HOST VARIABLE "NULL" * Null == null – UNDEFINED OR UNUSABLE HOST VARIABLE "NULL" * Null == 10 – UNDEFINED OR UNUSABLE HOST VARIABLE "NULL"

This comment was originally posted on Reddit

kolm

php is acting funny, as usual.

This comment was originally posted on Reddit

mauler

Isn’t that in ANSI SQL somewhere? I’m not sure, but at least in Oracle you can ORDER BY whatever NULLS FIRST or NULLS LAST to change the behavior.

This comment was originally posted on Reddit

tejoka

Er, no, no they should not be using undefined. That’s completely different.

This comment was originally posted on Reddit

albinofrenchy

Go ahead and explain to the rest of us how its completely different.

This comment was originally posted on Reddit

tejoka

_undefined_ has very different semantics. Nothing is the closest thing to null in Haskell, and has very similar semantics. 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? 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.

This comment was originally posted on Reddit

tejoka

yeah I replied again with an explanation just above. sorry. link just in case: http://www.reddit.com/r/programming/comments/91p9c/fun_with_none_truth_value_of_none_or_null_in/c0b4yne

This comment was originally posted on Reddit

albinofrenchy

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

albinofrenchy

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

This comment was originally posted on Reddit

rabidcow

> 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

master_troll

> 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

albinofrenchy

> 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

tejoka

> 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

keithjr

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

systeldesigns

Fun with none — The Uswaretech Blog – Django Web Development http://bit.ly/qEGHT

This comment was originally posted on Twitter

logan_capaldo

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

brool

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

bobbyi

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

rabidcow

> 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

snarfy

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

Cyrius

>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

logan_capaldo

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

This comment was originally posted on Reddit

logan_capaldo

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

divbyzero

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

becomingGuru

@zedshaw Here is how deep you can go: http://bit.ly/x7p7l
What about None>10 None==10 None

This comment was originally posted on Twitter

Post a comment Name :

Email :

Your site url:

Comment :

© Agiliq, 2009-2012