Live data from Hacker News

Null References: The Billion Dollar Mistake

infoq.com

131–140 of 158 posts

Re: Null References: The Billion Dollar Mistake

#131
post #73

Earlier quoted context omitted.

Can you give some more details on what the design problem is here? It seems to me that nullable references are isomorphic to having an option type with non-nullable references, but prevent accidental unchecked dereference. What are some of the difficulties that you'd expect to come up if you took an imperative language with nullable references and replaced them with options of non-nullable references?

I don't consider 'option' types to have interesting semantic differences with nullable types. YMMV. But beyond that, the absence of nullable references (really, a valid default value for every type) is a problem for record/object/struct initialisation - you either have to provide all values at allocation time, or attempt to statically check that the object is fully initialised before any use - Java has rules to that…

The difference is that you can't accidentally use an option as a pointer without checking it first, and when your APIs specify a non-nullable pointer you can rely on the callers to have checked for null.

When you're reading or writing a function that accepts a non-nullable reference, you never have to worry about whether the argument is null or not. It's easier to get right, constrains the scope of certain types of errors.

If you get things wrong, and unwrap the option without checking, you get an assert failure at that location, rather than potentially much later on when the pointer is used.

The whole point is that Option replaces nullable &Foo, so your record/object/struct member is Option and the default value for it is None. Option even has the same runtime representation for nullable &Foo, as Option uses NULL to represent None.

It's just a different way of representing nullable references, but with semantics that make it easier to track null-checked vs nullable references, impossible to accidentally get it wrong and derefence a nullable pointer you mistakenly assumed was already checked, and better errors when you do make mistakes.

Re: Null References: The Billion Dollar Mistake

#132
post #94

Earlier quoted context omitted.

The problem GP was raising is on the other half of Optional: when you do finally need an int. Say, you want to do arr[*increment(maybeInt)] //error: can't dereference Optional Now, if you as a programmer don't think increment(maybeInt) can actually return None in your particular case, you will probably do the minimal work to convince the compiler to let it go, say matchOptional( increment(maybeInt), someInt => {retur…

This is a corner case, though, and one that is itself a code smell (i.e. in well-written code, it should be very rare). Having implicit null references, and implicit null checks on dereference, optimized for rare a corner case to the detriment of safety in typical code patterns, is a bad thing. And it definitely is a significant source of errors in managed memory languages, from my experience in C# and Python. It can…

> Having implicit null references, and implicit null checks on dereference, optimized for rare a corner case to the detriment of safety in typical code patterns, is a bad thing.

Yes, I completely agree. I was just trying to point out that Optional is not a 100% air-tight solution, I think the problem of handling missing values is just too general to actually have a 100% solution.

Still, the perfect shouldn't be the enemy of the good, and default non-nullable definitely helps in most cases.

> It can also be pretty tricky to track down, when the code producing the null happens to run long before the code dereferencing it.

Here I don't agree. If the code producing the null is the problem, then you would have the same problem with Optional. Optional helps when code consuming the null forgot to handle the null case. If you're writing C# or Python and you get an NPE, and null was actually a valid value, you don't need to track down the source of the null, you just need to handle the null case in the exact case where the exception occurred (and possibly further downstream).

Re: Null References: The Billion Dollar Mistake

#133
post #83

Earlier quoted context omitted.

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.

Value and move semantics do the same thing and work in 90% of the cases a GC does. For the remainder there's ARC.

No, having to think about value and move semantics is extra overhead you take on. It's better when the compiler can help you catch this, like in Rust, but it still forces you to structure your program a certain way and to constantly think about incidental details like ownership.

Re: Null References: The Billion Dollar Mistake

#134
post #3

This comes up again and again in one form or the other, yet new languages still seem to be making the same mistake. Of all languages I've touched, Rust seems to be the only one that mostly circumvents this problem. Are there other good examples?

> Rust seems to be the only one that mostly circumvents this problem. Are there other good examples? Swift, Kotlin, and of course older languages of a functional bend like MLs, Haskell, Idris, Scala, … Some are also attempting to move away from nullable references (e.g. C#), though that is obviously a difficult task to perform without extremely severe disruptions.

[deleted]

Re: Null References: The Billion Dollar Mistake

#135
post #3

This comes up again and again in one form or the other, yet new languages still seem to be making the same mistake. Of all languages I've touched, Rust seems to be the only one that mostly circumvents this problem. Are there other good examples?

Elm is a great JS replacement on the frontend.

Re: Null References: The Billion Dollar Mistake

#136
I was expecting someone to mention the Crystal programming language.

In Crystal, types are non-nilable and null references will be caught at compile time.

https://crystal-lang.org/2013/07/13/null-pointer-exception.h...

I certainly recognize that many bugs in Ruby programs announce themselves as `NoMethodError: undefined method '' for nil:NilClass`. So to be able to catch that before releasing code is a very welcoming addition in my opinion.

Re: Null References: The Billion Dollar Mistake

#137

Earlier quoted context omitted.

Everything in Python is an object. In Python, containers are objects that reference other objects. https://docs.python.org/3/reference/datamodel.html https://docs.python.org/2.0/ref/objects.html

How are name bindings different than references? >>> a=[2, 3, 1] >>> b=a >>> id(a) 139731931982216 >>> id(b) 139731931982216 >>> b [2, 3, 1] >>> b.sort() >>> del(b) >>> a [1, 2, 3] >>>

Depends what you mean by reference. In Python they are indeed synonymous. C++ references are different in that the binding / object identity can be changed through the reference, eg when you pass a reference to a function.

Re: Null References: The Billion Dollar Mistake

#138

Count me amongst those who do not think they're a mistake. You need to indicate no-data-here in some fashion. If you try to use that no-data in some fashion having your program blow up from a null reference is a feature to me--in the vast majority of cases it's better go boom than silently continue doing something wrong. In the few where that's not the case you can trap the exception and go on. The real solution is w…

> You need to indicate no-data-here in some fashion.

Well languages that have non-nullable types still allow you to do that - you just have to be explicit about it. In TypeScript (using --strict mode which disables nullables), youd need to define the type as union type and make use of the "null" type: `let a: string | null`. So you tell the compiler that either "null" is a valid value for a or a string. The compiler will assist you and catch possible bugs (such as dereferencing a without checking it against null first)

Re: Null References: The Billion Dollar Mistake

#139

C.A.R Hoare couldn't foresee consequences 55 years ago. That's a small mistake. We should blame language designers who didn't bother to handle the problem after it's been obvious.

Lot of mainstream languages nowadays support non-nullable types, i.e. TypeScript and C# (taken from F#).

Re: Null References: The Billion Dollar Mistake

#140

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…

> 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. Perhaps it's just me, but I'd like to assume that my language does not treat any algorithm found in a basic algorithms course (e.g. Sedgewick) as awkward.

How times have you used doubly liked lists outside a CS101 programming exercise? Even if you did, it’d usually be trivial to implement an array index version or just use unsafe. Basically it seems you give up almost nothing for memory safety.
Post reply on HN