- is it Hindley-Milner based? (Rust, Haskell, OCaml)
- or does it support implicit subtyping (TypeScript, Flow, C#)?
The first: 1 expression <-> at most 1 type.
The second: 1 expression <-> multiple types.
A thread 👇
But implicit subtyping has trade-offs too:
const foo = () => Math.random() > 0.5 ? “bar” : 2;
In an ISTS, it's valid and the inferred returned type would be `string | number`.
In a HMTS, it would return a type error, as one branch has type `string` and the other `number`: they can’t be unified.
HMTS inference is restrictive: all conditional branches need to be "unifiable" into the same type.
What are the consequences?
1. we’re humans, and inferring types is a task better suited for machines (like compiling source code to assembly code)
2. our attention is now spread between writing code and inferring / writing types.
Plus, one can always use type annotations if needed (note that some features of HMTS-based languages might still require explicit annotations).
Before you give up on type systems, make sure you have meaningfully tried at least one in both categories! The developer experience is dramatically different.
Fin.
- "Subtyping is overrated", by @calebmer: (highly recommended!)
- waleedkhan.name/blog/union-vs-… by @arxanas
- codecommit.com/blog/scala/wha… by @djspiewak
- stackoverflow.com/questions/7234… (see quote by Scala's creator Martin Odersky)