Conversation

Don't have automatic zero initialization (or uninitialized data usage) and don't support null as a value for assignment to pointers. You won't have null pointers. An optional value isn't usually what's wanted and when it's desired it can and should be done explicitly instead.
1
3
I think the main reason that Go has null pointers is because for whatever reason they really wanted to support automatic zero initialization as the solution to uninitialized data, instead of forcing initialization before possible use via very trivial basic flow control analysis.
1
1
This means that every type in Go has a 'default' zero-based initialization, despite that often not making any sense. It causes a whole class of issues including but not limited to null pointers. I don't think it's good language design. I don't see a compelling reason to do this.
1
1
I like using languages with first-class tagged unions (sum types) and it steers a lot of the language design in the right direction. It covers the optional value case, provides a nice composable way to handle errors via type system support and steers it away from ugly features.
1
3
It makes it far less likely that the language is going to have exceptions and I'm not a fan of invisible control flow. Unpopular opinion based on wanting robust code compile-time errors instead of runtime: Java's checked exceptions are way less bad than the unchecked exceptions.
2
2
This Tweet is from a suspended account. Learn more
If you don't have them, you use a dedicated Option type instead. In a language with sum types, an Option type is a library feature. You can define your own version of it when it's more appropriate. In Rust, Option<&T> compiles down to the same size as &T. It's a nullable pointer.
1
1
That's an implementation detail but I'm pointing out that it compiles down to the same thing because it literally is a nullable pointer at runtime, but at compile-time it's a distinct type explicitly handled as such. You know when it's nullable, and it's not just for pointers.
1
1
So, for example, you can also return Option<u32>, such as for array.find(value) with arrays of not just pointers. In languages without sum types, you would be tempted to reserve a placeholder value (often incorrect), throw an exception or turn this into a more complex API.
1
I really think this is an essential feature. Even C has union types, and the high level version of that is a tagged union where it keeps track of the type and doesn't let you use it as the wrong type. In type theory, it's a sum type, while a tuple / struct is a product type.
1
1
In Rust, `enum Option<T> { Some(T), None }` and `enum Result<T, E> { Ok(T), Error(E) }` are the building blocks for error handling. In Haskell, the same things are `data Maybe a = Just a | Nothing` and `data Either a b = Left a | Right b`. It covers so many use cases though.
1
Rust and Swift present it as an enum where you can have anything as a variant rather than just enumerated possibilities without associated data. Those variants can reference the top-level type, for recursive data structures. It lets you directly spell out what JSON is as a type.
1