Hacker News new | past | comments | ask | show | jobs | submit login

Dart made the same nullable mistake but actually managed to fix it, which is quite impressive.

Go is just obstinately living in the 90s. I guess that's not really a surprise. It's pretty much C but with great tooling.




Dart has a great write up on how they fixed the null problem by adding non-nullable types: https://dart.dev/null-safety/understanding-null-safety


Several language have "fixed the null problem" after the fact, though usually as an opt-in e.g. typescript, C#.

The problem with Go (for this specific issue, there are lots of problems with Go) is that they have wedded themselves extremely strongly to zero-defaulting, it's absolutely ubiquitous and considered a virtue.

But without null you can't 0-init a pointer, so it's incompatible with null-safety.

I think C# pretty much left the idea of everything having a default behind when they decided to fix nulls. Though obviously the better alternative is to have opt-in defaulting instead.


This is a good point. Null pointers are the billion-dollar mistake, but the real billion-dollar mistake is having "zero values" in your language. In addition to the problems with null pointers, zero values make loose constructor semantics like C# and Java tempting, where objects can exist in a not-fully-initialized state, leading to lots of room for confusing bugs. Without zero values to fall back on as a crutch, the language design is forced to tighten that up so that objects are either completely initialized or completely uninitialized, like in ML or Rust†, which is a much cleaner semantics. (The funny thing is, Go has the tools to get rid of zero values by virtue of not having constructors, but it chose not to use them for that!)

† Strictly speaking, objects can be partially initialized and partially uninitialized in Rust, but this is harmless as the borrow checker statically ensures that uninitialized fields of objects are never accessed.


Yeah technically you can always default init fields to None, but then you have to type everything as an Option and the ergonomics are so bad you're really incentivised not to do that. In that case you bundle that in a transient structure (a builder) and you get rid of it afterwards.


Or you use MaybeUninint, which I think is a great example of how unsafe Rust exposes to potential memory unsafety but grants you control when you need it.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: