[clean-list] exceptions again (a bit long, but this might actually be correct)

Marco Kesseler m.wittebrood@mailbox.kun.nl
Thu, 29 Jan 2004 22:37:41 +0100


On Thu, 2004-01-29 at 09:19, fzuurbie@inter.nl.net wrote:
> Marco Kesseler wrote:
> > 
> > Here is the hole: f (x + y) may not equal f (y + x), because the (lazy)
> > evaluation of (x + y) within f may throw a different exception than the
> > evaluation of (y + x). And for different exceptions, h a e may differ.
> > This is a serious problem that destroys referential transparency.
> > 
> 
> On second thought I am not convinced. In my opinion it destroy
> communtativity of +, not referential transparency. Classical +
> seems to be commutative even for limited precision integers, but
> various 'laws' don't hold for them. For instance: a+b-a is not
> generally equivalent to a-a+b, notably as a approaches the largest
> integer that can be represented. But issues like this make the
> difference between (theoretical) calculus and (practical) computation,
> and dealling with them has become a craft by itself.

Again, to be clear: the hole is not part of the new proposal.

That being said, yes it did destroy referential transparency. The
commutativity problem is just one manifestation of this problem. Suppose
we have:

add x y = x + y.

Then f (add x y) should equal f (x + y). Not so in the old proposal. A
compiler might choose to evaluate x first for "add", and y first for
"+". And as x may throw a different exception than y - and as f catches
them - we loose f (add x y) = f (x + y).

The new proposal avoids this, as it does not allow exceptions in
arguments to be caught in f itself. Also see the reply to Simons
message.

> > This problem however, _only_ occurs for lazily evaluated arguments (as
> > far as I can see). If f is strict in its argument a, exceptions can only
> > occur during the evaluation of g.
> 
> Well, even strict arguments run the risk of being evaluated - and throw an
> exception, whether it is caught within f or outside.

Strict argument are always evaluated before you enter f. So once f
starts evaluating, these can no longer introduce an exception there.

> > Back to the problematic lazily evaluated argument "a". Isn't it weird
> > that f encounters exceptions that arise during evaluation of its
> > argument "a"? The computation of "a" can involve anything, and maybe f
> > should _not_ be made responsible for handling any exceptions in it.
> 
> I like this idea.
> 
> > 
> > So suppose that we define that catch statements can only catch
> > exceptions that arise from definitions that are explicitly contained
> > _in_ that function definition? Either directly or indirectly. In other
> > words: if an exception occurs while evaluating the argument "a", it will
> > _never_ be caught in f, but propagated outward. Only exceptions that
> > originate in g will be caught by f.
> > 
> > -- So what? --
> > 
> > Well, that may be enough to solve the problem mentioned above: if (x +
> > y) raises an exception, then f (x + y) will _not_ have a function value
> > either, but it will also lead to an exception.
> 
> What do you mean ALSO? Do we have two exceptions in one calculation here? 

No. I meant to say that the same exception has the effect that both the
expression (f (x + y)) and its subexpression (x + y) have no value.
Evaluating either (x + y) or (f (x + y)) leads to the same exception, as
if f has no catch statement.

> > And so will f (y + x),
> > regardless whether f contains a catch statement or not.
> > 
> Well, f (x+y) and f (y+x) still might throw different (sets of) exceptions,
> just because x+y and y+x might. 

Yes, that is true. But the point here is that f cannot catch it. So
someone else has to. Now, this must be done within a function that leads
to the construction of (x + y), or (y + x).

For a particular set of arguments, is it _known_ whether this catching
function will lead to (x + y) or (y + x). And thus, it is known which
exception will get raised for a particular set of arguments. And thus,
everything stays deterministic.

> > 
> > If any of you find a hole in this proposal, I am sure you let me know,
> > and I'll try crawling through some dust.
> > 
> 
> Maybe I am confused by the particular example x+y vs y+x that seems
> to lose commutativity rather than referential transparency. Instead
> of crawling through the dust, you might be able to come up with an
> example that really loses ref. transparency.

In the new proposal I can't. In the old proposal, see the remarks above
about (f (add x y)) not being equal to (f (x + y)).

regards,
Marco