ADTs and strictness

1993-10-05 Thread Simon L Peyton Jones



(This message assumes we head for the strictness-annotation-on-constructor-arg
solution. I'll respond to Phil's comments in my next msg.)

The problem with polymorphic strictness
~~~
John asks what the problem is with strict constructor args.  As Lennart and
Kevin say, the problem only really arises with function types; for example

data Foo = MkFoo !(Int - Int)

Operationally the idea is that you evaluate the function before building the
constructor.  That places some new constraints on implementations, but I suspect
it can always be done.  

More seriously, as Lennart says, Haskell says that _|_ = (\x - _|_).
Now, there is no way to find out whether the function given as an
argument to MkFoo is a function which always returns bottom. Consider

case MkFoo (\x - a complicated calculation involving x, which 
  always fails to terminate)of
   MkFoo f - 0

If the implementation just "evaluates the function" and then wraps it in a MkFoo,
then the result of this expression is just 0.  But if _|_ = (\x - _|_),
and MkFoo really is strict, then the result should be _|_.

So, as Lennart says, if we allow constructors to be strict in functions
then we have to change the semantics to distinguis _|_ from (\x - _|_).
I, for one, am deeply reluctant to do so; I certainly have no good handle on
the consequences of doing so.  Does anyone else?

The problem shows up if a constructor is strict in a polymoprhic position:

data Baz a = MkBaz !a !a

(consider Baz (Int - Int))

All this applies equally to polymorphic seq too, of course.


An alternative
~~
We already have a good mechanism for dealing with problems like this; it's
called overloading.  Suppose we had a class

class Data a where
   seq :: a - b - b
   -- Other things too?

There would be an instance for class Data on every algebraic data type, 
automatically derived.

Then we could write

data Data a = Baz a = MkBaz !a !a

and everything is fine, because now Baz can only be applied to data types, not
functions.  And we get seq too.  The annotation in the MkBaz can be explained by
translation to seq.

Implementations are free to implement seq with a single batch of polymorphic
code if they want, of course.

Ain't that easy?  The only tiresome thing is having to write Data a = in places
where you want a strictness annotation on a polymorphic constructor arg.  But I
don't mind that one bit.

The only infelicity is that in the special case of single constructors with a
single strict arg (ie the kind we need for ADTs) there is no need for the 
arg to be in class data:

data Abstract a = MkAbstract !a

is perfectly ok semantically and pragmatically.  I suppose one could allow
the (Data a =) constraint to be omitted in this special case.  Or give a
different syntax for ADT decls, as I suggested before.

Simon




Re: ADTs and strictness

1993-10-05 Thread Gerald Ostheimer


 So, as Lennart says, if we allow constructors to be strict in functions
 then we have to change the semantics to distinguish _|_ from (\x - _|_).
 I, for one, am deeply reluctant to do so; I certainly have no good handle on
 the consequences of doing so.  Does anyone else?

I thought this inequality was one of the distinguishing characteristics of
lazy functional programming relative to the standard lambda-calculus. To
quote from Abramsky's contribution to "Research Topics in Functional
Programming", Addison-Wesley 1990:

   Let O == (\x.xx)(\x.xx) be the standard unsolvable term. Then

   \x.O = O

   in the standard theory, since \x.O is also unsolvable; but \x.O is in
   weak head normal form and hence should be distinguished from O in our
   "lazy" theory.


Gerald






Re: ADTs and strictness

1993-10-05 Thread wadler


Gerald Ostheimer notes that in Abramsky and Ong's lazy lambda calculus
that (\x - bottom) differs from bottom.  That's correct.

But just because they call it `lazy' doesn't mean that it really is
the essence of laziness.  I prefer to use the more neutral name `lifted
lambda calculus' for their calculus.

An example of a perfectly good lazy language in which neither products
nor functions are lifted is Miranda (a trademark of Research
Software Limited).

Hope this clarifies things,  -- P






ADTs and strictness

1993-10-05 Thread Sergio Antoy


I have been following this discussion with interest and I'd like
some clarification.

Wadler writes:

 But just because they call it `lazy' doesn't mean that it really is
 the essence of laziness.

What is really been called `lazy' and how is the `essence of
laziness' defined?

Also, forgive my ignorance, but what does it mean that 'products
or functions are lifted'?

Thanks,

Sergio Antoy
Dept. of Computer Science
Portland State University
P.O.Box 751
Portland, OR 97207
voice +1 (503) 725-3009
fax   +1 (503) 725-3211
internet [EMAIL PROTECTED]