10 ms·
Credible empirical investigations of programming language efficiency are too hard to carry out (though they could be done in principle). However, what we can d
by mafribe 11y ago
Credible empirical investigations of programming language efficiency are too hard to carry out (though they could be done in principle).
However, what we can do instead is look the evolution of programming languages: what features do the latest creations have, what features are older languages retro-fitted with? What ideas have seen little uptake?
(i) Higher-order functions: Yes, slam-dunk win. Essentially all new languages have them, Java and C++ retrofit them.
(ii) Lazy evaluation order by default: mostly dead. All new language use eager evaluation, even SPJ is sceptical that lazy evaluation should be the default. Scala has an interesting approach: eager by default, but you can switch to CBN (although not full laziness) if required. This hybrid form enables you to define control-operators easily, while keeping the simplicity and efficiency of eager evaluation. Exceptions are
languages with dependent types that are really theorem provers (e.g. Agda).
(iii) Purity: dead. All new languages have side-effects. The widely used FP languages like Haskell, Ocaml and F# have side-effects. Exceptions are
languages with dependent types for Curry-Howard-based theorem provers (e.g. Agda), because there is no convincing Curry-Howard correspondence using state.
(iv) Everything is function application: open. This may work reasonably well in purely sequential languages, but there are theoretical reasons to believe that message passing is not function application (while function application is a special case of message passing).
(v) Types. The answer on this one depends on whether one is a proponent of statically typed languages or not, clearly an unresolved question. For dynamically typed languages, the question is moot, so the rest of the discussion is irrelevant to those who think that static typing is a bad idea.
(vi) Types (1), type inference: Slam dunk winner. All new languages have inference or wish they could have it but don't know how to do it (Scala). There are probably some hard trade-offs between expressivity of types and efficient decidability of type inference (B Pierce termed Hindley-Milner a "sweet spot"), so we might have to tolerate some type annotation being required, e.g. in local or bidirectional inference.
(vii) Types (2), algebraic data types, pattern matching: winner. Most new languages have them in some form.
(viii) Types (3), monadic encapsulation of effects: open. Most new languages have not yet embraced this. Some conceptual problems not yet solved, e.g. destructors for state monads. There are also expressivity problems, e.g. not all effects can easily be expressed as monads, and composition of monads doesn't always work as desired. Moreover there are pragmatic questions about whether monadic encapsulation should be required or optional.
(ix) Types (4), higher-kinded types: open. Not all new languages have them, but HKTs are generally considered useful, but not super important, cf Rust's evolution. If monadic encapsulation of effects is used, then HKTs become highly desirable, cf the recent Scala fork.
--------------------
Any other suggestions?
- lmm 11y agoIs purity dead? Do you consider Idris a theorem prover? It's dependently typed but seems to be designed for writing operational programs rather than proofs.
- mafribe 11y agoI'm not familiar enough with Idris to know exactly how state is handled, but yes, Idris is a prover, since it has dependent types. If you want to verify your programs (and in 99.9% of programs you probably don't as you get it sufficiently correct by more lightweight techniques such as testing and code-reviews), then purity is fine, since you have to track effects explicitly anyway to prove non-trivial results, and doing this in a pure functional way or say with auxiliary variables in a Hoare-logic are kind-of/sort-of notational variants.
- lmm 11y agoIf "prover" just means "has dependent types" then that's a much larger class than it sounds like. I write a lot of Scala, which has dependent types, but most of the code I write is just ordinary web services.
- mafribe 11y agoI meant dependent types a la Agda, Coq etc that you can use for proving essentially arbitrary properties. Scala and Haskell do not have this.
- lmm 11y agoI don't understand the distinction you're drawing. Idris' type level functions are easier to write than Scala's but they don't seem to be able to do anything that Scala ones can't.
- tel 11y agoTo be clear, Haskell "has dependent types" to various degrees as well.