
On Tue, Mar 20, 2007 at 01:53:47PM +0000, Malcolm Wallace wrote:
Now, in the definition x = x `seq` foo one can also make the argument that, if the value of x (on the lhs of the defn) is demanded, then of course the x on the rhs of the defn is also demanded. There is no need for the `seq` here either. Semantically, the definition is equivalent to x = foo I am arguing that, as a general rule, eliding the `seq` in such a case is an entirely valid and correct transformation.
So does nhc98 print "Foo" for this program? main = putStrLn $ let x = x `seq` "Foo" in x (yhc tells me my program has deadlocked, but my recent attempt to compile nhc98 failed so I can't check it). I don't fully understand what your interpretation is; is it also true that y = x x = y `seq` foo is equivalent to y = x x = foo ? And is it true that y = if True then x else undefined x = y `seq` foo is equivalent to y = x x = foo ?
The objection to this point of view is that if you have a definition x = x `seq` foo then, operationally, you have a loop, because to evaluate x, one must first evaluate x before evaluating foo. But as I said at the beginning, `seq` does _not_ imply order of evaluation, so the objection is not well-founded.
I'm having trouble finding a non-operational description of the behaviour I think seq should have. (Nor, for that matter, can I think of a description that makes it clear that it has the semantics that you think it should have). Anyone? I think you could make a similar argument that let x = x in x :: () is () rather than _|_, and similarly let x = x in x :: Int is 3, or is there some key difference I'm missing? Thanks Ian