CS52 - Fall 2015 - Class 18
Example code in this lecture
digit_addition.sml
mutual_bad.sml
mutual.sml
mutual2.sml
compose.sml
Lecture notes
admin
- midterms back on Thursday
handling exceptions
- Quick recap:
- declaring exception
exception A;
- to raise an exception, you just put:
raise A
somewhere in the code
- If we call a function (or do an operation) that could raise an exception, we can try and catch/handle it
- In Java, this is done as:
try{
code_with_possible_exception
}catch(name_of_exception){
code_to_run_if_exception_happens
}
- In SML, it is similar, but the syntax is different
code_with_possible_exception handle
name_of_exception => code_to_run_if_exception_happens
- In SML both code_with_possible_exception and code_to_run_if_exception_happens need to be expressions that represent the same type
- If you want to handle multiple expressions (like having multiple catch statements in java), you can just list more of them using |
exceptions with more information
- the exceptions we've seen so far don't have any information except that an exception has occurred
- we can also declare exception to bring extra information along:
exception B of string;
exception C of int;
exception D of (int * int);
- These statements declare an expression that must have extra information when it is raise, e.g.
raise B "something bad happened";
raise C 0;
raise D (1,-1);
- In the handle expression, you can then access this information, e.g.
code_with_possible_exception handle
(B s) => ...
| (C n) => ...
| (D t) => ...
look at
digit_addition.sml code
- simple set of code for doing digit-wise operations
- it's a little contrived, but it allows me to illustrate the points
- operation defines a new type for the 4 operations we will support
- BadOperation is the exception that we will raise
- checkDigit
- checks to make sure it's a valid digit
- if not raises an exception with information
- if it is, simply returns the value
- eval
- evaluates an operation on two inputs
- note that checkDigit might raise an exception
- or we might raise it if we find divide by 0
- eval2
- does the same thing
- shows an example of handling an exception without any extra information
- DivByZero is the exception that is raised by the system if you try and divide by 0
- calculate1
- calls eval and handles the exception using the option type
- calculate2
- calls eval and returns a string
- if it works, it has the answer
- if there is an exception, it prints the message
look at
mutual_bad.sml code
- What do these two functions do?
- determine if a number is even or odd
- How do they do it?
- a number is even if the number minus 1 is odd
- a number is odd if the number minus 1 is even
- What will happen if I try and "use" this file?
- SML is going to complain!
- in isEven, isOdd isn't defined yet.
- Can I just switch the order of the two function?
- No! Then isEven won't be defined
mutually recursive functions
- These functions are what are known as mutually recursive functions
- They are two functions that are recursive, but recurse by call eachother, i.e. A calls B and B calls A.
- In SML, we have to tell the compiler that functions we're declaring are mutually recusive.
- Look at
mutual.sml code
- to do this, instead of ending the first function with a semicolon we move on to the next line and begin the next function with "and" instead of "fun"
- you can do this for as many functions as you'd like
- SML will wait to examine all of the functions until a semicolon is reached.
Look at
mutual2.sml code
- What do these functions do?
- select every other element from a list
- everyOtherEven starts with the 2nd element
- everyOtherOdd starts with the 1st element
function composition
- In math, if we have two functions:
f(x) = x+2
g(x) = x*x
- what is the composition of those two function (written f o g)?
f(g(x))
- In SML, we can also compose functions using the composition operator "o" (lowercase o)
- For SML functions f and g, what are the type requirements for us to compose them, f o g?
- f: 'a -> 'b
- g: 'c -> 'a
- and the composition returns a function, of type 'c -> 'b
look at
compose.sml code
- what do the following return?
c1 8
c2 8
c3 8
- 100
- 66
- 100
parsing
EBNF syntax
EBNF for numbers:
N ::= [S]D[F]
S ::= '+' | -
F ::= .D
D ::= (0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9)+
EBNF syntax
- EBNF = Extended Backus-Naur Form
For example:
- -10
S = -
D = 10
- 15.2
D = 15
F = .
D = 2
- +12
- 17
- -10.542
Binary operations
- 5 operators
- work bitwise
- 5 & 4 = 101 & 100 = 100
- 5 | 4 = 101 & 100 = 101
- !5 = !101 = 010
- Some more complicated ones
- 110 & 100 | 011 = ?
- order of operations!
- !
- &
- | and ^
- ->
- 110 & 101 | 100 = 100
- !110 & (101 | 100) = 001 & 101 = 001