From: pcg@aber.ac.uk (Piercarlo Grandi)
Newsgroups: comp.lang.misc
Subject: Re: PL/1 non-local goto versus setjmp/longjmp
Date: 23 Aug 92 18:28:04 GMT
	<mwm.1jk3@contessa.palo-alto.ca.us> <id.KTGS.0N5@ferranti.com>
	<1992Aug20.074423.4841@cs.rug.nl>
Reply-To: pcg@aber.ac.uk (Piercarlo Grandi)
Organization: Prifysgol Cymru, Aberystwyth

On 20 Aug 92 07:44:23 GMT, laverman@cs.rug.nl (Bert Laverman) said:

	[ ... non local control transfer ... ]

laverman> [Impressive demonstration by Peter removed] I'm sorry, but
laverman> aren't you just implementing Exceptions here?

Ah, one of my pet peeves! To bad for you! :-)


There is *absolutely no way* to implement exceptions. There is no such
thing as an exception that can be implemented. Virtually all the
research (includig voluminous Ph.D. thesises, proceedings, books, ...)
on exception is misguided and pointless.

There have been even incredibly ridicolous attempts to have exceptions
as language entities, and the ensuing and toally pointless discussions
(should they be a first class data type? should they be statically or
dynamically scoped? and son on...) have provided cannon fodder for many
a silly debate.


On the other hand there is some relationship between 'exception
handling' and non nested control transfers, and maybe it will be useful
if I make it clear.

First of all, let's talk of what an 'exception' is: it is a *fact*,
not a language construct, or value, it is the fact that the state of the
computation has become undefined.

This happens iff a procedure implements a non total function, and the
procedure is applied outside that function's codomain.

This happens iff the precondition of a branching construct is weaker
than the union of the preconditions of the branches. For example,
computing

	3 / 0

is undefined because in the implementation of the / procedure (whether
it be microcode, hardwired, macrocode) there is something like:

  if
    divisor == 1 ->	  quotient = dividend;
  | powerof2(divisor) ->  quotient = shiftright(divident,log2(divisor));
  | not powerof2(divisor)
    and divisor <> 1
    and divisor <> 0 ->	  quotient = newt_raph_div(divisor,dividend);
  fi

So, 'exception handling' is just making all procedures implement total
functions. Unfortunately this is in general cannot be done at procedure
definition time, because extending certain functions so that they become
total can be done in several different ways, and there cannot be
previous agreement as to how.

For example in some cases division by zero should return a token for
'infinite', in some case it should return zero, and so on.

Therefore, 'exception handling' should normally consist in completing
all branching statements so that their precondition is never weaker than
the unions of those for their branches, and each new branch should be a
call to a *dynamically* scoped procedure name.


for example:

  if
  | divisor == 0 ->	  quotient = div_by_zero(divisor,dividend);
    divisor == 1 ->	  quotient = dividend;
  | powerof2(divisor) ->  quotient = shiftright(divident,log2(divisor));
  | not powerof2(divisor)
    and divisor <> 1
    and divisor <> 0 ->	  quotient = newt_raph_div(divisor,dividend);
  fi

The body of div_by_zero may then contain any arbitrary logic that the
programmer of the upper levels of the program wishes.

In particular two choices seem to be common for the body of such a
procedure, and they are returning a 'default' value, or doing a non
local control transfer to higher level handling code. In the latter case
the dynamically scoped procedure does not just substitute for the
"missing" branch, but also for a number of intervening abstraction levels
that depend on the outcome of that branch.

It is only in the second case that non local control transfers enter the
'exception' handling picture at all; in such a case they are required,
but they are useful for many other reasons.

Unfortunately there is some silly tradition by which even relatively
serious authors pretend that exceptions are 'objects' or language
'entities', or exception handling is made to coincide with non local
control transfers, or other entirely inappropriate perversions.
--
Piercarlo Grandi                   | JNET: pcg@uk.ac.aber
Dept of CS, University of Wales    | UUCP: ...!mcsun!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@aber.ac.uk