Live data from Hacker News

Null References: The Billion Dollar Mistake

infoq.com

51–60 of 158 posts

Re: Null References: The Billion Dollar Mistake

#51
post #35

Earlier quoted context omitted.

No, obviously not. Every domain having a Nil element is exactly the problem null references have introduced (at least for the call by reference parts of the affected languages).

Null is a single nil for all, I meant having a null per domain would force people to think of what it means to have nothing in that field and handle it. Maybe I'm too naive.

> I meant having a null per domain would force people to think of what it means to have nothing in that field and handle it.

In what way would it change anything? The "billion dollars mistake" is that because "nothing" is part of every type, any value you get could really be missing, and you have to either hope for the best (and die like the rest) or program ridiculously defensively.

Having a magical sentinel per type would have the exact same issue, namely that "nothing" is part of the type itself, and so you can never be sure at compile time that you do have "something".

That's what opt-in nullability (whether through option types or language builtins or a hybrid) changes, by default if you're told you have an A it can only be a valid A, and if you're told you might have an A you must either check for it or use "missing-safe" operations.

Re: Null References: The Billion Dollar Mistake

#52
post #25

Earlier quoted context omitted.

Plus also doesn’t the stack need to be small to fit into the CPU cache?

There is absolutely no requirement from the hardware that the stack be any particular size

I am not thinking requirement by rather performance wise.

Re: Null References: The Billion Dollar Mistake

#53

Earlier quoted context omitted.

Sometimes you don't want to allow a value to be null at all, but with null references you can't represent that at the language level.

But for numbers, a zero is not considered null, because it was handled in the operators rules.

Numerical zero has nothing to do with the issue discussed here. What you are proposing is to add another “number” to types like int and float that results in the program crashing whenever you try to add it to another number.

Re: Null References: The Billion Dollar Mistake

#55

"Making everything a reference: The Billion Dollar Mistake" is the talk I want to see

Everything in Python is a reference, and there's no null pointer issues.

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

Re: Null References: The Billion Dollar Mistake

#56
post #53

Earlier quoted context omitted.

But for numbers, a zero is not considered null, because it was handled in the operators rules.

Numerical zero has nothing to do with the issue discussed here. What you are proposing is to add another “number” to types like int and float that results in the program crashing whenever you try to add it to another number.

I think it does

Re: Null References: The Billion Dollar Mistake

#57
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?

Functional programming languages have been doing it for ages. Most "newer" statically typed languages also have it (Swift, Kotlin, Rust) by default. And old languages had it bolted on (C# 8, Java 8, C++ 17). I think at this point basically everyone has realized null by default is a terrible idea.

> And old languages had it bolted on (C# 8, Java 8, C++ 17).

C#: actually true, you can switch over to non-nullable reference types

Java 8: meeeh, it provides an Optional but all references are still nullable, including references to Optional. There are also @Nullable and @NotNull annotations but they're also meh, plus some checkers handle them oddly[0]

C++17: you can deref' an std::optional, it's completely legal, and it's an UB if the optional is empty. Despite its name, std::optional is not a type-safety feature, its goal is not to provide for "nullable references" (that's a pointer), it's to provide a stack-allocated smart pointer (rather than have to allocate with unique_ptr for instance).

[0] https://checkerframework.org/manual/#findbugs-nullable

Re: Null References: The Billion Dollar Mistake

#58

This old chestnut again. There is an inherent problem in designing processes and writing code to capture them: The notion of not-a-value. There are great many ways to solve them. The most common ones are 'null' and 'Optional[T]'. Neither just makes the problem magically go away. If a process is designed (or a programmer writes it) thinking that 'ah, well, here, not-a-value cannot happen', but it can, then.. you have…

The goal of `Optional[T]` is not to "make the problem magically go away", in fact that is almost the opposite of the goal. Optional[T] exists to make it very obvious when a value is nullable. Having non-nullable types as default, with Optional[T], allows a developer to model a system more accurately. This is helpful both to the compiler as well as anyone else who reads/maintains that code. > Imagine, for example, in…

Sure it's up to the language design, but in practice a `None` gets a similar treatment as an empty collection, usually effectively short-circuiting remaining calculations. As the parent poster pointed out, this might either be the behavior you want, or actually mask the error, depending on the situation. By this logic, optionals aren't better than null refs, just different. The same argumentation holds for exceptions vs optionals.

Re: Null References: The Billion Dollar Mistake

#60
post #13

This old chestnut again. There is an inherent problem in designing processes and writing code to capture them: The notion of not-a-value. There are great many ways to solve them. The most common ones are 'null' and 'Optional[T]'. Neither just makes the problem magically go away. If a process is designed (or a programmer writes it) thinking that 'ah, well, here, not-a-value cannot happen', but it can, then.. you have…

I remember tracking down the null silent message failure issue in the early 1990s on NextStep. Then again almost 2 decades later on the iPhone. Personally, I’m not a fan of silent failures. IMHO, allowing for non-nullable variables is a huge improvement in language design. Adding boilerplate annotations is an ugly way to handle it. Optimize for the common case and make variables non-nullable by default.

In my experience, forbidding null refs usually only results in getting null objects instead, such as empty strings or empty collections. Thats not bad, but might not solve such a silent error message, you'll still end up with an empty message in the end. In order to solve it proper, I'm thinking you'd might want to go further and have more expressive type constraints, like Ada subranges.
Post reply on HN