logoalt Hacker News

hutaotoday at 3:19 AM0 repliesview on HN

I've always felt that ML hit the sweet spot between functional and imperative programming. It affords conveniences such as algebraic data types and first-class functions, but unlike Haskell, it doesn't require monadic programming to use IO or mutable references.

ML also has an interesting module system, which achieves similar goals as object-oriented programming, but in a very different way. While mainstream "class-based" OOP identifies the data type with the unit of encapsulation, ML has "modules," which are separate entities from types, and which may both define types and values as members. However, a downside of this approach is that you sacrifice late binding, as the module language and "core" language are stratified into different layers. Instead, dependency injection is achieved through module-level functions, called functors,

A lesser-known fact is that ML originated as the scripting language for the LCF proof assistant (which is where the name "ML," or meta language, comes from). In the LCF tradition, the inferences rules of the logic are implemented in a trusted kernel, then clients use those inference rules to write tactic scripts that construct theorem objects. This design was supported by ML's module system: theorems were defined as an abstract type in a "kernel" module, and the inference rules were defined as functions inside the module. Here is a tutorial that explains the LCF design better than I can: https://www.cs.cmu.edu/~fp/courses/15317-f17/recitations/rec...