> 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 a bug.
> Some language features might make it possible to help reduce how often it occurs, but eliminate it? I don't think so.
On the contrary, you can 100% eliminate it by forcing null handling at compile time with your `Optional` type. Haskell and some other strongly-typed languages do this (but they call it Maybe).
The way to do this in a C-syntax-ish language would look something like this:
Optional increment(Optional i) {
// return i + 1; would throw an error at compile time,
// because Optional doesn't implement the + operator
// i.applyToValue would throw an error at compile time
// if you didn't handle both possible cases
return i.applyToValue(
ifNull: (void) => { return new Optional(null); },
ifValue: (int i) => { return i + 1; }
);
}
This is syntactically a bit heavy, partly because I was a bit more verbose than a real implementation would need to be, for clarity, and partly because C-style syntax doesn't do this well. Languages that support this generally have some syntactic sugar to make it a bit more terse.
I've argued before on HN that the benefits of strong static typing are overstated, but this is a case where strong static types really do completely eliminate an entire category of errors. Given how common these errors are, not using stronger types in this situation for popular languages has absolutely been a billion dollar mistake.