The problem is that many languages don't make the distinction in the type system. Why oh why do we not force everyone to null check every time?
This makes 95% of the problems associated with nil/null pointers magically disappear. The difference this makes for the safety of large-scale systems is huge.
Yeah, and it's also not popular. The reason I said "popular" is because the popular languages are addressing pain-points for devs.
If nil/null was a pain point, none of the popular languages would allow nil/null values.
The simple fact is that, for many developers, there is a pressing need to indicate lack of a value. Languages that don't address this pain-point never really get taken up en masse.
Almost every new language that has come out in the last ~10 years or so tries hard to avoid null pointers, and old languages try very hard to mitigate the problem in various ways.
Dart went through a tedious process of removing nullability.
Kotlin doesn't have nullability (well, sort of, using Java bindings can still get you null pointer exceptions).
There are lot's of attempts for Java, from static analysis tools (eg recently from Meta , but there are older solutions), Springs new @NonNull, etc.
C# switched to making non-nullable the default a few years ago.
Rust only has null pointers in the unsafe part of the language, and only for low level raw pointers, not for traits.
Go is the odd one out.
That strawman is not the argument. The argument is that "popular languages have it, so it must be solving some problem".
You can say what you like about popularity, but it still remains a good indicator of what works in practice and what doesn't, especially when the alternatives are all well-known and have been around for decades.
Popular amongst Rust fans, certainly. Popular amongst employers, no. It's still barely a rounding error for employers.
[1] https://www.theregister.com/2022/12/02/android_google_rust/
I find it likely that Rust in the Linux kernel will not be used for anything important (other than architecture-specific code) until either it can be compiled using GCC (either the GCC backend for the Rust compiler, or the Rust frontend for the GCC compiler), or the LLVM backend supports every single architecture supported by the Linux kernel (or the Linux kernel loses support for the architectures the LLVM backend doesn't support).
I have to nitpick here: Rust raw pointers (https://doc.rust-lang.org/std/primitive.pointer.html which does note "Working with raw pointers in Rust is uncommon") do have null values. It's not usually a problem since raw pointers can only be dereferenced in unsafe code; most of the time, you will be using a reference wrapped with an Option, which has the same size and same possible values (the compiler knows a reference is never null, so it uses the "missing" null value to represent the None variant of the Option enum).
Sure, and "unsafe" is not only a huge red flag but can and should be tightly scoped and can then be audited much easier than chasing around NPE through an entire Class or even codebase.
Secondly, I've used Rust for a few years now and have NEVER needed to or thought of using raw pointers once. It's unnecessary for almost every single usecase I can think of except maybe OS or driver development but even then you can tightly control where "unsafe" uses pop up.
Languages which just have one nullable type here like Go must use their "might be a dog" type to represent things which definitely are a dog, meaning either you write paranoid checks everywhere or you might screw up - and it's no wonder there are more bugs as a result.
All popular languages have some way to encode the fact that a value is absent.
When languages that don't support nil/null values become popular, you might have a point in claiming that it was a mistake.
Right now it makes no sense to make that claim.