Hoare—the null reference inventor—as "the billion dollar mistake"[2] From a Programming Languages perspective, it's reasonable to say that flow-sensitive typing is the feature that finally made it possible to build usable type-safe programming languages with union types and without rampant dynamic checking.
Until this point, attempts to add this feature to languages such as Scheme generally resulted in intractably large type representations.
One example of a system with limited support for union types is Wright and Cartwright's "Soft Scheme.
[15] Pattern matching reaches the same goals as flow-sensitive typing, namely reducing verbosity and making up for terser code, easier to read and modify.
Pattern matching works best when used in conjunction with algebraic data types because all the cases can be enumerated and statically checked by the compiler.