bug in language definition (strictness)

Simon Marlow marlowsd at gmail.com
Fri Aug 7 03:57:30 EDT 2009


On 06/08/2009 17:42, Malcolm Wallace wrote:
>>
>>>> What semantics would you like Haskell to have, in which (x `seq` y
>>>> `seq` e) and (y `seq` x `seq` e) are not equal?
>>>
>>> I can easily imagine that (x `seq` y `seq` e) might have *two* semantic
>>> denotations: bottom (Exception: stack overflow), and e. And I would like
>>> to be able to choose which one I get (please). This is the declared
>>> purpose of seq, namely "to improve performance by avoiding unneeded
>>> laziness".
>>
>> I'm afraid I don't really comprehend what you're getting at. What do
>> you mean by an expression having two semantic denotations, and how
>> would you like to choose which one you get? And I'm baffled by the
>> mention of stack overflow, where does that come in?
>
> Whether it is a stack overflow, or some other kind of resource-related
> exception like out-of-memory, or too-many-open-file-handles, does not
> really matter. As you were saying, semantically they are all just bottom.
>
> My real point is that seq looks for all the world like it is intended to
> affect the operational behaviour of a program, yet some people insist
> that it is a purely denotational device, and that operational questions
> are not relevant.

The fact remains that seq *is* defined denotationally, and any 
implementation that respects its semantics is legal.  If you want to 
change that, you need to make a Haskell Prime proposal.

I think it might be difficult to do that.  The Haskell report has no 
framework for talking about operational semantics at all.  The pure 
subset of Haskell is timeless, there's no specified evaluation order. 
Before we think about changing that, let's remember why it's that way: 
one reason is that evaluation order doesn't affect the denotational 
semantics, so it's unnecessary.  Another reason is that it lets Haskell 
admit many different implementations, including things like automatic 
speculative parallelism.  If you start nailing down evaluation orders, 
you rule out interesting implementations.  (this is why I've complained 
about lazy I/O in the past - it starts to creep in this direction).

There's nothing stopping you from making a compiler in which seq has the 
behaviour you want.  Indeed, Control.Parallel.pseq is the kind of seq 
you want (I think - we haven't put any thought into precisely specifying 
what it means).  pseq is a valid implementation of seq, it's just not 
the one we normally want to use, because it restricts the compiler's 
ability to optimise.  And pseq isn't something we want to mandate in the 
language, because it only makes sense in certain kinds of 
implementations.  I'm completely happy with asking users to use pseq 
when they really want an evaluation order guarantee.

> Yet I think it would be
> valid to say that seq can turn a non-terminating (exceptioning) program
> into a terminating one.

Do you have an example of that?

Cheers,
	Simon


More information about the Haskell-prime mailing list