Live data from Hacker News

Null References: The Billion Dollar Mistake

infoq.com

151–158 of 158 posts

Re: Null References: The Billion Dollar Mistake

#151
post #99
post #90

Earlier quoted context omitted.

You directly see where the null dereference happens. But that's not necessarily where the problem actually is, because a null pointer can flow through a lot of code before it actually gets dereferenced. So "program continues to work for a while" is also a thing with them. In a language like C, a null pointer can also become an invalid non-null pointer pretty easy with pointer arithmetics.

Easy, just add "if (thing == null) return;" to the top of the function that crapped out on a null reference and close the ticket! /s

Sarcasm aside, this is often how it gets fixed in poor quality codebases! And if it returns a reference itself, it ends up being:

   if (thing == null) return null; 
more often than not. Which leads to an even more entertaining debuggin trip next time...

Re: Null References: The Billion Dollar Mistake

#152
post #80

Earlier quoted context omitted.

> You directly see when and where it happens, and the fix is usally straightforward. This is not true in most dynamic languages, especially ones where I/O is not typed. You have to be extremely dilligent about verifying input. JavaScript comes to mind.

> You have to be extremely dilligent about verifying input. That's true of all languages. Null references are a problem of low effort development. Calling it a billion dollar mistake is sensationalist hand-wringing. It accidentally highlighted how carelessly most programs are written, implying that without it developers wouldn't be checking inputs as strictly, because they wouldn't need to. Yes it's another type, but…

Almost all bugs could be called the result of "low effort development", but if there's a class of bugs that simply does not need to exist, why would you want to keep it around?

The reason to pull Null is that it's easy to forget to check, and it causes bugs. Lots of bugs. Lots of wasted developer time.

The real question is if there is any reason to keep it, and I'm pretty sure the answer is no. Expressing nullability in the type is an infinitely better solution.

Re: Null References: The Billion Dollar Mistake

#153

Earlier quoted context omitted.

> It's exactly the same as langages with null pointers: Four huge differences: 1. You don’t need to pass around ‘Maybe a’ everywhere. If null isn’t expected as a possible value (which usually it isn’t), you just pass around ‘a’, and when you do use ‘Maybe’ it actually means something. 2. The Haskell compiler can, and does (with -Wall), tell you that your pattern match is non-exhaustive. You don’t need a separate “lin…

> You don’t need to pass around ‘Maybe a’ everywhere. You don't need to pass pointers around everywhere. Languages with null still have value types that cannot be null. > You don’t need a separate “linter or whatever”. Optional compiler flags count as "whatever" to me. > it’s not undefined behavior like in C that could result in something weird and unpredictable happening later (or earlier!) C++ doesn't define this,…

Oh boy... `-Wall` is "whatever". Please let me never look at code you have written...

Re: Null References: The Billion Dollar Mistake

#154
post #141

Earlier quoted context omitted.

> You have to be extremely dilligent about verifying input. That's true of all languages. Null references are a problem of low effort development. Calling it a billion dollar mistake is sensationalist hand-wringing. It accidentally highlighted how carelessly most programs are written, implying that without it developers wouldn't be checking inputs as strictly, because they wouldn't need to. Yes it's another type, but…

> there hasn't been a demonstrative reason to pull it" is not the reason it's not "been pulled Languages are hard to change and backwards compatibility is paramount. Hell, some languages support null just for interoperability (i.e. Scala) when they would have otherwise not allowed it when they were created. Null isn't expressive and is historical baggage. At this point "billion dollar" is probably an understatement.…

Lots of languages have several ways to indicate an invalid value.

With SQL, I generally prefer dialects where an empty string and null are considered the same, although that may be just due to what I learned first. Various Microsoft technologies seem to tend towards multiple ways of expressing null/missing/empty.

An interesting thing about null in SQL is that the rule that any operation on a null returns null, only applies sometimes in some contexts. For instance in Oracle SQL:

select max(case when x = 'ABC' then 'ABC' end) as y from ...

...is taking the maximum of an expression which is null whenever x 'ABC', yet it doesn't return null if there are rows where it does = 'ABC'.

(sorry for any errors)

Re: Null References: The Billion Dollar Mistake

#155

Earlier quoted context omitted.

> there's even a book teaching how to implement doubly linked lists in Rust [1] Doubly-linked lists are an awkward example because the "safety" of a doubly-linked list as a data structure involves fairly complex invariants that Rust can't even keep track of at this point, much less check independently. These things are exactly why the unsafe{} escape-hatch exists and is actively supported. But just looking at the amo…

I’m a rust fan, but garbage collection is about removing having to think about memory management from the developer almost entirely, not about performance.

I don't do the sort of programming recently where it matters, but when I read the debates on GC on HN, I think, why not a language where there is a GC, but it is "cooperatively scheduled" - you explicitly invoke it for a fixed amount of time. Wouldn't that be the best of both worlds?

Re: Null References: The Billion Dollar Mistake

#156

Earlier quoted context omitted.

Good list. I've found the consequences of a nil type are less severe in dynamic languages, where all variables have the Any type, since nil is just one of the options one needs to account for. Static languages where everything is nullable are reneging on the promise; you say something is a String but that just means Option , and it saps a lot of the reasoning power which static typing should give.

Even in dynamic languages, the consequences can be pretty bad. For example, I've seen lots of Ruby bugs where things end up being unexpectedly `nil`, but I haven't seen as many Python bugs where things end up being unexpectedly `None`. How does this happen? Well, in Ruby it's a lot more normal to just return nil. For example, consider the following code snippet: [][0] In both languages you are trying to examine the z…

That seems (although I don't have experience with either language) straightforwardly correct treatment in Python and wrong in Ruby, and the problem seemingly should be attributed to [lack of] range checking, not nil/null.

Re: Null References: The Billion Dollar Mistake

#157
post #99

Earlier quoted context omitted.

Easy, just add "if (thing == null) return;" to the top of the function that crapped out on a null reference and close the ticket! /s

Sarcasm aside, this is often how it gets fixed in poor quality codebases! And if it returns a reference itself, it ends up being: if (thing == null) return null; more often than not. Which leads to an even more entertaining debuggin trip next time...

Oh for sure. I wish I would have thought of that sarcastic quip by being creative, but in reality it's because I've seen it so many times.

Re: Null References: The Billion Dollar Mistake

#158

Earlier quoted context omitted.

Even in dynamic languages, the consequences can be pretty bad. For example, I've seen lots of Ruby bugs where things end up being unexpectedly `nil`, but I haven't seen as many Python bugs where things end up being unexpectedly `None`. How does this happen? Well, in Ruby it's a lot more normal to just return nil. For example, consider the following code snippet: [][0] In both languages you are trying to examine the z…

That seems (although I don't have experience with either language) straightforwardly correct treatment in Python and wrong in Ruby, and the problem seemingly should be attributed to [lack of] range checking, not nil/null.

Sure; in this case, range checking provides an alternative behavior to generating a null reference. But Ruby has other places where it generates null references more promiscuously than Python. Java does too. If you take every use case that could generate a null reference and instead behave differently in that situation you’ve eliminated null references, and Python has largely done so despite having a None type.
Post reply on HN