> Haskell's design, which is built around extensional/value semantics, which basically approximates a program/subroutine as the function it computes; this is a useful approximation as it lets us treat computations as if they were referentially transparent. That approximation has a cost, though, as computations are not quite functions (they are processes that compute functions)
This sounds "not even wrong" to me. Care to explain in more detail?
> If, OTOH, your language has continuations ... monads don't really help.
What exactly is unclear? In Haskell, a subroutine or a subprogram is modeled as a mathematical function. Programs are not exactly functions[1] but continuations (i.e., they are a process which can be paused and resumed). There's absolutely nothing wrong with abstracting computations as functions (and there's much to be gained, which is why programmers are encouraged to write pure functions where possible, regardless of the language they're using), but sometimes you need to use their continuation-quality, and that's when you need monads.
> Haskell has continuations. Your move.
No, it doesn't. It models continuations as monads which is precisely my point. If Haskell subroutines were continuations, it wouldn't need monads, just as OCaml doesn't.
[1]: If they were, then computations would be extensionally equivalent like functions, but they're not: an observer can tell if you're running bubble sort or merge sort, even though they're computing the same function (which is why type theory introduces has the concept of definitional equality). A lambda term or a Turing machine are not functions but continuations; you can start reducing a lambda term (or running a TM), block it (i.e. capture the reduced term/TM state), and then resume it.
I think you must be using a very non-standard definition of continuation. What exactly is your definition of continuation? In what way exactly does OCaml "have" them that Haskell doesn't?
You are right in that I am using the word continuation to highlight an important property of computational models (be they lambda calculus, Turing machines, or FSMs), namely the ability to stop and resume a computation. In imperative languages, subroutines are continuations in the sense that they can block and then be resumed (although only some languages have reified continuations that allow direct manipulation of the suspended continuation, as opposed to supporting just scheduling by the OS, although theoretically scheduling by the OS is enough to capture the expressive strength of continuations, albeit that it suffers from various performance problems). In Haskell, subroutines are functions and have no notion of "blocking". Because that notion is essential to computations, it is emulated in Haskell by composing functions together with monads rather than being supported "natively".
But Haskell pure functions do "block" when they request memory from the allocator, for example. How do you distinguish these two kinds of blocking so you can claim that OCaml has it and Haskell doesn't.
In the sense that this blocking can be fully or partially reified. I don't know much about OCaml's implementation of their lwt library, so I'll give an example from Java: In Java you can create a thread running a single subroutine, have that block by calling `park`, and then hold on to that blocked function in a form of a reified object (the thread), which you can resume at any time. This is not possible in Haskell, you cannot hold onto blocked subroutines (i.e. continuations); instead, you hold onto a chain of functions connected via a monad (or monads).
> This is not possible in Haskell, you cannot hold onto blocked subroutines (i.e. continuations); instead, you hold onto a chain of functions connected via a monad (or monads).
I don't understand what this means, and I certainly don't understand the difference between the two things.
This means that Haskell doesn't have an object representing a function blocked in mid-operation. The difference is one of abstraction (obviously all languages can ultimately express all computations), which affects composition and mental overhead. These, of course, are empirical effects, and so their merits cannot be justified on any theoretical grounds (theoretically, monads and continuations are the same).
This sounds "not even wrong" to me. Care to explain in more detail?
> If, OTOH, your language has continuations ... monads don't really help.
Haskell has continuations. Your move.