Exception Handling in ML


Exception definition

  exception  of 

    exception Baz; (* no arguments *)

    exception Foo of string;
      raise Foo("bar");


Exception handling
If a raised exception is not handled, computation always stops.

   handle 
  here we fear that some exception may be raised in 
  the "handle" section will deal with all exceptions we fear


  exception OutOfRange of int * int * string;

  fun safe_comb(n,m) =
    if n <= 0 then raise OutOfRange(n,m,"")
    else if m < 0 then raise OutOfRange(n,m,"m must be greater than 0")
    else if m > n then raise OutOfRange(n,m,"n must be greater than m")
    else if m=0 orelse m=n then 1
    else safe_comb(n-1,m) + safe_comb(n-1,m-1);

  fun comb(n,m) = safe_comb(n,m) 
    handle
      OutOfRange(0,0,mess) => 1
    | OutOfRange(n,m,mess) => 
         ( print("out of range: n="); print(n); 
           print(" m="); print(m); 
           print("\n"); print(mess); print("\n"); 
           0 
         ) ;


Built-in exceptions

MORE EXAMPLES

fun expo (x, 1) = x
  | expo (x:int, y) = x * expo(x, y-1) ;

fun inverse x = 1.0 / x
  handle Div => ( print("divide by zero produces 'infinite' value: "); 
                  real(expo(10,10))






Information Hiding in ML

A cluster of definitions (datatypes, functions, exceptions) can be bound together in a structure.

Signatures allow tailoring of structures for reuse, for use by multiple persons, etc.

Functors allow abstracting out common code from several related uses.

Local blocks

One more way to hide some elements in a structure:

  local  < definitions >
  in    < more definitions >
  end

Here the definitions after the "local" can be used in those after
the "in", but they cannot be seen outside the block.  However,
all definitions after the "in" are visible outside.

"local" block can go anyplace you have a list of definitions
(like in a structure).
It is simply a fence around some of the definitions in the list.

This in not like "let"... in "let" a list of expressions must
follow the "in"

Example


structure Foo = struct

  local
    exception bad_help ;
    fun helper x = 
       ...
       if (oops) raise bad_help ;
       ;
  in
    fun op1 x = 
      ...
      if (need_help) then helper(k);
      ...
      ;

    fun op2 x = ... ;
    fun op3 x = ... ;
    fun op4 x = ... ;
  end;
    
end;