5 ms·
Read about sum types. They exist in Haskell, Rust, OCaml, Typescript, Swift, Kotlin, etc. You are likely only familiar with product types without knowing they
by brobinson 4y ago
Read about sum types. They exist in Haskell, Rust, OCaml, Typescript, Swift, Kotlin, etc. You are likely only familiar with product types without knowing they're called product types. (Cartesian product)
You can have 100% type-safe, guaranteed at compile time code without null that can still represent the absence of data. Once you've used sum types, you feel clumsy when using Javascript, Python, Go, Ruby, C, C++, etc. especially when refactoring. Nullness infects your data model and always comes out of nowhere in production and ruins your day.
- davidatbu 4y agoTo be fair to Python, the static typing doesn't have the billion dollar mistake (you have explicitly say `Optional[int]`, for eg).
- nicoburns 4y agoArguably dynamic languages have sum types: every variable is one big sum type with the variants being every other type! I suspect the lack of sum types in many static languages are partially responsible for the popularity of dynamic ones.
- davidatbu 4y agoVery interesting perspective!
- kortex 4y ago> I suspect the lack of sum types in many static languages are partially responsible for the popularity of dynamic ones. I can totally see this. I started writing a small cli tool in Go, and despite knowing way less Rust, I switched to it and was able to make a lot better progress at first due to pattern matching and result types. It was just so much easier/more ergonomic to write a simple parser. The Go code was a mishmash of ugly structs and tons of null checking and special casing.
- int_19h 4y agoSome statically typed languages have union types that are extensible in a similar fashion; e.g. in OCaml: https://v2.ocaml.org/manual/polyvariant.html https://v2.ocaml.org/manual/polyvariant.html
- estebank 4y agoI would say that traits are a better analogy for dynamic types, but at the same time you can think of enums as closed sets and traits as open sets, so they are different ways of encoding sets of possible structure and functionality, more alike in what they provide than it initially seems.
- nailer 4y agohttps://old.lispcast.com/what-are-product-and-sum-types/ https://old.lispcast.com/what-are-product-and-sum-types/ That was easy to understand. > You can have 100% type-safe, guaranteed at compile time code without null that can still represent the absence of data. If it's a single score, I'd still want to use null / int. There no invalid states being represented, anything else is still unnecessary complexity. > Nullness infects your data model and always comes out of nowhere in production and ruins your day. A TS example: trying to do anything with 'score' where score is `null | number`, would be caught be the compiler.
- brobinson 4y ago>If it's a single score, I'd still want to use null / int. In your example, you still have to manually check if there's a value every time, but this is not compiler-enforced. Should you forget, you will get a runtime crash at some point (likely in production at a critical time) with some kind of arithmetic error. This wouldn't be possible with a simple sum type. Also, a sum type with units of Score(Int) and NoScore won't allow assignments of any other "null" instances. Null in one spot is interchangeable with null in any other spot, and this can lead to bugs and runtime crashes. Null should be avoided when possible.
- nailer 4y agoThe compiler would enforce Number-ness every time I try and run a function that takes a number, right? Wouldn’t I still have to check for NoScore? > a sum type with units of Score(Int) and NoScore won't allow assignments of any other "null" instances. I get this part - I wouldn’t be able to assign ‘NewBornBaby’ (my name null) to ‘NoScore’ (my score null)
- brobinson 4y ago>Wouldn’t I still have to check for NoScore? That's right, and the compiler will reject programs where you don't do this. It's a set of safety rails for your code. You pay a dev-/compile-time cost in exchange for your programs not exploding at runtime.