Fri, 26 Jan 2001 15:53:51 -0500
Marko Schuetz <MarkoSchuetz@web.de> replies to me as follows:
> > He uses this, and an argument based on currying, to show that strict
> > functions ought to force their arguments left to right.
> I can't see where I did. I argued that distinguishing between error
> and bottom seems to not leave much choice for bottom + error.
You're right, sorry. I misread the following from your earlier
> So I'd say error + bottom \equiv bottom and bottom + error \equiv
As you noted:
> and you want, say, error + bottom \equiv error then + can no longer be
> strict in its second argument....
I'd managed to turn this around in my head.
Nonetheless, my fundamental argument stands: If we separate "bottom"
and "error", we have a few choices operationally, and I'm not fond of
1) Make "error" a representable value. This appears closest to what
you were describing above:
case ERROR of x -> expr => expr [ERROR/x]
This is tricky for unboxed types (especially Ints; floats and
pointers aren't so hard; note that we need more than one
distinguishable error value in practice if we want to tell the user
something useful about what went wrong).
At this point, by the way, it's not a big leap to flatten the
domain as is done with IEEE NaNs, so that monotonicity wrt errors
is a language-level phenomenon rather than a semantic one and we
can handle exceptions by testing for error values.
2) Weaken the algebraic theory as I discussed in my last message.
3) Reject an operational reading of "case" as forcing evaluation and
continuing and have it "do something special" when it encounters
case ERROR of x -> expr => ERROR glb expr[?/x]
From the programmer's perspective, I'd argue that it's *better* to
signal signal-able errors whenever possible, rather than deferring
them. If nothing else, a signaled error is easier to diagnose than
nontermination! Thus, I'd LIKE:
error + bottom === error
But I'm willing to acknowledge that I can't get this behavior
consistently, except with some sort of fair parallel execution.
I'm doing something along the lines of (3), but I abandon execution
immediately on seeing error---which is consistent only if
case ERROR of x -> expr => ERROR
[Indeed, the compiler performs this reduction statically where
possible, as it gets rid of a lot of dead code.]
I defer the signaling of errors only if the expression in question is
being evaluated eagerly; for this there is no "case" construct