4 ms·
Those implementations are useful as empirical tests of what works/doesn't. However, it's also useful to keep such academic debates going; since it's unlikely t
by chriswarbo 4y ago
Those implementations are useful as empirical tests of what works/doesn't.
However, it's also useful to keep such academic debates going; since it's unlikely that our current abstractions are the most optimal. For example:
- Hoare added `null` to Algol because it was pragmatic; and he later regretted it. In contrast, "academics" like Milner added algebraic datatypes to ML, which turned out to provide a much safer alternative (Option/Maybe).
- "Pragmatic" languages like Python, Javascript, etc. added try/throw for exceptional control-flow. Then added for/yield for resumable control-flow. Then added async/await for concurrent control-flow. Meanwhile, "academics" refined Scheme's call-with-current-continuation into shift/reset, which allows all of those to be written in libraries, rather than having to keep changing the language implementation.
- Languages like ML and Scheme used call-by-value, which happened to make side-effects quite pragmatic. Meanwhile "academics" debated call-by-need semantics, Moggi figured out that effects are monadic, and Wadler added it to Haskell. That enabled a bunch of functionality that would have been undermined by the presence of side-effects (e.g. implicit parallelism, software-transactional memory, parser combinators, promises/futures, etc.)