3 ms·
To discuss this properly, you need to consider the evaluation strategy, which is part of the semantics of the language. Strict, lazy, call-by-need: things do ge
by theoh 8y ago
To discuss this properly, you need to consider the evaluation strategy, which is part of the semantics of the language. Strict, lazy, call-by-need: things do get evaluated in a prescribed order, and sequencing using monads (predictably) involves strictness, meaning that a function argument is evaluated before the function.
These details of evaluation order are important to know, and they are not something to be argued about: they are well-specified and the compiler doesn't just casually make lazy code into strict code or vice versa. That would cause chaos. And what instruction set Haskell is being compiled to is totally irrelevant to this level of the language's semantics.
https://en.wikipedia.org/wiki/Evaluation_strategy https://en.wikipedia.org/wiki/Evaluation_strategy
- JadeNB 8y ago> To discuss this properly, you need to consider the evaluation strategy, which is part of the semantics of the language. Yes, you are certainly right. I misread and thought incorrectly that the discussion was about whether certain constructs forced data dependencies in any theoretical language, not in the particular language Haskell. > These details of evaluation order are important to know, and they are not something to be argued about: they are well-specified …. While I take your meaning, I think that you don't mean literally what you said: they got to be well specified precisely by being argued about, and will hopefully get to be even better specified by continuing argument. They are certainly not for me to argue about, though.
- foldr 8y ago>sequencing using monads (predictably) involves strictness, Sequencing using the IO monad predictably involves strictness. There is nothing in the type of >>= that forces strictness. That is why, for example, you can usefully bind infinite lists in the list monad. So in e.g. [1..] >>= return . (+ 1), the list is not evaluated before the call to (+). In fact, binding is not strict in the IO monad either (that's why lazy IO works). It's only the special magic world parameter that is, in effect, evaluated strictly.
- theoh 8y agoYes, monads don't imply strictness. The idea of using a data dependency to force a certain order of evaluation predates monads and it predates laziness. So it is implemented accordingly, and any hoops that need to be jumped through in the implementation to make it work aren't magic—they are just necessary to express a long-established pattern. What monads offer is a way of discreetly passing the state from one operation to the next (the State monad is the model for the IO monad). It removes the need for the programmer to think about that aspect of the plumbing, without creating magic elements in the language. http://okmij.org/ftp/Computation/IO-monad-history.html http://okmij.org/ftp/Computation/IO-monad-history.html
- foldr 8y ago>So it is implemented accordingly, and any hoops that need to be jumped through in the implementation to make it work aren't magic—they are just necessary to express a long-established pattern. The hoops are magic in the sense that they can't be expressed in Haskell 98 or Haskell 2010. A Haskell compiler is perfectly entitled to optimize out any dummy values which aren't used. That includes dummy world variables. More generally, it simply isn't possible to use data dependencies -- even real data dependencies -- to control the order of side effects. The Haskell standards just don't provide the guarantees necessary to make that workable, for the reasons that millstone gave.