[comp.lang.ada] Exceptions as generic parameters

emery@MITRE-BEDFORD.ARPA (Emery) (06/29/87)

While we are on the topic of language 'deficiencies', here's one of my peeves:

I would like to pass exceptions to generics. Consider the following:

  generic
    type t is private;
    with procedure try_to_print_t (a_t : t);
      -- what happens if try_to_print raises an exception?
      -- in particular, I know that there may be problems printing t, whatever
      -- t may be.  If there is a 'printing' error, I would like to recover 
      -- from it separately from other errors (such as program_error...)
  procedure print_with_caption (a_t : t; caption : string);

Here are two 'candidates' for the generic:

  package one is
    type t is string(1..20);
    procedure print_t (a_t : t);
    non_printing_char_in_string: exception;
  end one;

  package two is
    type t is (red, green, blue, black, white);
    procedure set_color_attribute (to_color : t);
    not_a_color_terminal : exception;
  end two;

Now, in the body of generic print_with_caption, I would like to handle the
an error in printing separately than all other errors, i.e. I would like to 
do some real error recovery.  (In this case, I will probably ignore printing
errors, but re-raise other errors).

Either the generic unit must 'with' all possible instantiators, and do 'case
analysis' on the possible exceptions, or it must use the 'when others' clause,
and hope for the best.  

Here's what I would like to say:

  generic
    type t is private;
    with procedure try_to_print_t (a_t : t);
    error_printing_t : exception;	-- exception raised in try_to_print_t
  procedure print_with_caption (a_t : t; caption : string);

Types, objects and subprograms can be passed to generics, why not exceptions?

				
				dave emery
				emery@mitre-bedford.arpa

sdl@MITRE-BEDFORD.ARPA (07/06/87)

Like Dave Emery, I have often wished for the ability to define a
generic that takes an exception as a parameter.   Making the generic
definition directly visible at the point of the generic definition (either
by scope or context specification) is *not* an entirely desirable
alternative, because it may be the wrong coupling.  You often want the
exception to be grouped with the code that raises it, not with the
code that contains potential handlers for it.

However, I am concerned about the possible ambiguities/aliasing that
generic exception parameters may introduce, and whether this poses
potential problems for compiler writers.  Consider:


    generic
      E: exception;
    procedure FOO is
      X : FLOAT;
    begin
      . . . .
      X := {expression raising NUMERIC_ERROR};
    exception
      when E =>   {some handler}  ;
    end FOO;


    procedure MY_FOO_C is new FOO (E => CONSTRAINT_ERROR);
    procedure MY_FOO_N is new FOO (E => NUMERIC_ERROR);
  

In MY_FOO_C, the expression raising NUMERIC_ERROR would cause a control
transfer to the end of FOO (no handler).  In MY_FOO_N, the expression
would cause transfer to the exception handler for E (bound to
NUMERIC_ERROR).  

This means that the control flow of the generic body could not be
entirely determined when the generic is compiled.  (This might also
cause some problems with optimization of exceptions.)  Rather, some
table-driven scheme would be needed that would resolve such control
flow ambiguities at instantiation time.

The issue is whether code that raises the predefined exceptions is
compiled & optimized the same way that user-defined exceptions are
treated.  If so, then generic exception parameters shouldn't be too
difficult.

Would any Ada compiler gurus like to comment?


Steven Litvintchouk
MITRE Corporation
Burlington Road
Bedford, MA  01730
(617)271-7753

ARPA:  sdl@mitre-bedford.arpa
UUCP:  ...{cbosgd,decvax,genrad,ll-xn,philabs,security,utzoo}!linus!sdl