Folks Following a good deal of email I now propose to DO NOTHING to the rules defining do-notation in the Haskell 98 Report. That means that GHC and Hugs, and nhc perhaps, should change so that they actually implement the do-notation translation rule do {e ; stmts} = e >> do {stmts} using (>>) and not (>>=).
From my reading of the email, some people will agree strongly, and no one will disagree strongly. I suppose I could be wrong about this, though.
Simon
| do {e ; stmts} = e >> do {stmts} With the risk of being late at this, and with the risk of repeating something that has already been said (because I have been away), I will give my two euro-cents. I remember a discussion at the Haskell mailing list about the possibility of creating a nasty space leak with this translation. After all, there is a difference between: <e1> >> <e2> which, for the default definition of >> expands to an expression which is operationally equivalent to: <e1> >>= let x = <e2> in \_ -> x, and: <e1> >>= \_ -> <e2>. In the first case, x is shared between successive invocations, but in the second case, e2 is recomputed. I remember that the example involved a definition like: f = do ...; print [1..] In the translation in the report, the list [1..] is shared between all invocations of f, whereas the current GHC translation does not. So, changing the translation in GHC might actually introduce a very nasty space leak in existing programs! /Koen. -- Koen Claessen http://www.cs.chalmers.se/~koen Chalmers University, Gothenburg, Sweden.
On Sun, Apr 14, 2002, Koen Claessen wrote:
| do {e ; stmts} = e >> do {stmts}
With the risk of being late at this, and with the risk of repeating something that has already been said (because I have been away), I will give my two euro-cents.
I remember a discussion at the Haskell mailing list about the possibility of creating a nasty space leak with this translation. After all, there is a difference between:
<e1> >> <e2>
which, for the default definition of >> expands to an expression which is operationally equivalent to:
<e1> >>= let x = <e2> in \_ -> x,
and:
<e1> >>= \_ -> <e2>.
In the first case, x is shared between successive invocations, but in the second case, e2 is recomputed.
I remember that the example involved a definition like:
f = do ...; print [1..]
In the translation in the report, the list [1..] is shared between all invocations of f, whereas the current GHC translation does not.
If I understand this correctly, this only comes up when full laziness is used. Since full laziness turns space-efficiency upside-down, it does not seem to make much sense to try to tweak the Report to make things work better with full laziness. Note: I think it could be pretty cool to have something like full laziness that depended on programmer annotations: f p = let x = e1 in e2 would not save the value of x across calls to f, but f p = letfl x = e1 in e2 would save it. Something like this could be used for those cases where full laziness makes programs easier to read/write/understand without bothering people in cases where it is a bad idea.
So, changing the translation in GHC might actually introduce a very nasty space leak in existing programs!
-- Night. An owl flies o'er rooftops. The moon sheds its soft light upon the trees. David Feuer
participants (3)
-
David Feuer -
Koen Claessen -
Simon Peyton-Jones