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.

  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) 
      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"); 
         ) ;

Built-in exceptions


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: "); 

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 >

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"


structure Foo = struct

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

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