Presentation is loading. Please wait.

Presentation is loading. Please wait.

ML Exceptions.1 Standard ML Exceptions. ML Exceptions.2 Exceptions – The Need  An extensive part of the code is error handling  A function can return.

Similar presentations


Presentation on theme: "ML Exceptions.1 Standard ML Exceptions. ML Exceptions.2 Exceptions – The Need  An extensive part of the code is error handling  A function can return."— Presentation transcript:

1 ML Exceptions.1 Standard ML Exceptions

2 ML Exceptions.2 Exceptions – The Need  An extensive part of the code is error handling  A function can return an answer, or fail to find one, or signal that a solution does not exist.  We can try to use ML datatypes:’ datatype int sol = Success of int | Failure | Impossible  Using special return values can be tedious, and requires explicit handling every time case methodA problem of Success s => Int.toString s | Failure => (case methodB problem of Success s => Int.toString s | Failure => "Both failed" | Impossible => "No Good") | Impossible => "No Good“  Sometimes we don’t really know what to do with the error, so we we’ll return a sol…

3 ML Exceptions.3  Separates the exceptional path from the normal path  Upon error, we raise an exception fun hd [] = raise Empty | hd (x::xs) = x  A raised exception is called packet  The packet propagates … fun add_hd xs ys = (hd xs) + (hd ys)  … up to the first point where a handler for it exists val x = add_hd [1] [] handle Empty => 1  The caller of a function doesn’t have to check any of the error values  The whole expression is a single expression Using Exceptions

4 ML Exceptions.4  We can raise only a specific type: the built-in type exn  The type exn is a special datatype with an extendable set of constructors and values  Declaring exceptions - values of type exn - exception Failure; - Failure; val it = Failure(-) : exn  Declaring exceptions – Constructors: - exception Problem of int; - Problem; val it = fn : int -> exn The Exception type exn

5 ML Exceptions.5  In normal expressions, exn behaves pretty much like a regular datatype (though it is not an equality type)  Values of type exn have all the privileges of values of other types - val x = Failure ; (* Failure is a value *) val x = Failure(-) : exn - val p = Problem 1; (* Problem is a constructor *) val p = Problem(-) : exn - map Problem [0, 1, 2]; val it = [Problem(-),Problem(-),Problem(-)] : exn list - fun what's_the_problem (Problem p) = p; Warning: match nonexhaustive Problem x =>... val what's_the_problem = fn : exn -> int The Exception type exn

6 ML Exceptions.6  raise Exp The expression Exp of type exn is evaluated to e raise Exp evaluates to an exception packet containing e Packets are not ML values  Packets propagates under the call-by-value rule  Which means that all of the following evaluate to raise Exp f (raise Exp) (raise Exp) arg raise (Exp1 (raise Exp)) (* Exp1 is constructor *) (raise Exp, raise Exp1) (* or {a=Exp, b=Exp1} *) let val name = raise Exp in some_expression end local val name = raise Exp in some_declaration end Raising Exceptions - Semantics

7 ML Exceptions.7 The Computation of take fun take (0, _) = [] | take (n, x::xs) = x :: take (n-1, xs) | take (n, nil) = raise Empty fun reverse3 xs = rev (take (3, xs)) - reverse3 [1,2]  rev (take (3, [1, 2]))  rev (1::take (2, [2]))  rev (1::(2::take (1, [])))  rev (1::(2::raise Empty))  rev (1::raise Empty)  rev (raise Empty)  raise Empty

8 ML Exceptions.8  General form: Exp_0 handle P1 => Exp_1 |... | Pn => Exp_n  Assuming Pis are disjoint, this is equivalent to (((Exp_0 handle P1 => Exp_1) … ) handle Pn => Exp_n)  All Exp_i must be type-compatible  All Pi must be valid pattern for the type exn  Calculating length using exceptions - fun len l = 1 + len (tl l) handle Empty => 0; Handling Exceptions - Syntax

9 ML Exceptions.9 Exp_0 handle Cons1 x => Exp_1  Assume Exp_0 evaluates to some value V Then the value of this expression is: Exp1 If Exp_0 evaluate to raise Cons1 x V otherwise. V may be either a normal value, or a non-matching raised exception.  Handle is a short-circuit operator, like if-then-else  All this is exactly equivalent to the familiar notions from C++ Handling Exceptions - Semantics

10 ML Exceptions.10 The Computation of len fun tl [] = raise Tl | tl (x::xs) = xs fun len xs = 1 + (len (tl xs)) handle Tl => 0; - len [3]  1+(len (tl [3])) handle Tl=>0  1+(len []) handle Tl=>0  1+(1+(len (tl [])) handle Tl=>0) handle Tl=>0  1+(1+(len (raise Tl)) handle Tl=>0) handle Tl=>0  1+(1+(raise Tl) handle Tl=>0) handle Tl=>0  1+(raise Tl handle Tl=>0) handle Tl=>0  1+0 handle Tl=>0  1 handle Tl=>0  1

11 ML Exceptions.11  The expression raise Exp is of type ‘a  Technically described as “t for some arbitrary type t”  It is NOT an expression of type exn!  Within context, it simply puts no restriction on other parts of the expression: - fun throw _ = raise Empty; val throw = fn : 'a -> 'b - fun bar x = if x>0 then x else raise Underflow; val bar = fn : int -> int  Theoretically, It may be type-checked as type None (aka Bot) or something similar to datatype ‘a Ex = ‘a The Type of raise Exp

12 ML Exceptions.12  Example: If methodA fails then methodB is tried case methodA problem of Success s => Int.toString s | Failure => (case methodB problem of Success s => Int.toString s | Failure => "Both failed" | Impossible => "No Good") | Impossible => "No Good"  Exceptions give a shorter and clearer program. Error propagation does not clutter the code. toString (methodA problem handle Failure => methodB problem) handle Failure => "Both failed“ | Impossible => "No Good" Using Exception Handling - More

13 ML Exceptions.13 - raise Problem; Error: argument of raise is not an exception [tycon mismatch] raised: int -> exn in expression: raise Problem -hd [“good”] handle nil => “bad” ; Error: handler domain is not exn [tycon mismatch] handler domain: 'Z list in expression: hd ("good" :: nil) handle nil => "bad" | exn => raise exn Error Messages

14 ML Exceptions.14 Exam Questions  What is the response 1. local exception E of string; in fun f (E “Hello”, E x) = x; end 2. let exception Exy of int in (fn 2 => raise Exy 4 | x => x+x) 2 handle Exy n => n end

15 ML Exceptions.15 Standard Exceptions Some built-in exceptions Chr is raised by (chr k) if k 255 Match is raised for failure of pattern-matching. e.g. when an argument matches none of the function’s patterns, if a case expression has no pattern that matches, etc. Bind is raised if the value of E does not match pattern P in the declaration val P = E


Download ppt "ML Exceptions.1 Standard ML Exceptions. ML Exceptions.2 Exceptions – The Need  An extensive part of the code is error handling  A function can return."

Similar presentations


Ads by Google