# lecture-5

Document Sample

Quiz                  Example
let f x =
fun z -> x + z;;

let inc = f 1;;
let dec = f (-1);;

inc 5;;
dec 10;

Example               Another example
let x = 1;;
let f x =
let f y = x + y;;
fun z -> x + z;;
let x = 2;;
f 5;;
let inc = f 1;;
let dec = f (-1);;

inc 5;;
dec 10;

Another example       What about more complex data ?
let x = 1;;           • We’ve seen some base types and values:
let f y = x + y;;        – Integers, Floats, Bool, String etc.
let x = 2;;
f 5;;                 • Some ways to build up types:
– Products (tuples), records, “lists”
– Functions

• Design Principle: Orthogonality
– Don’t clutter core language with stuff
– Few, powerful orthogonal building techniques
– Put “derived” types, values, functions in libraries

1
Next: Building datatypes                                Each of
Three key ways to build complex types/values            1. “Each-of” types
1. “Each-of” types                                      Value of T contains value of T1 and a value of T2
Value of T contains value of T1 and a value of T2
Where have we seen this?
2. “One-of” types
Value of T contains value of T1 or a value of T2

3. “Recursive”
Value of T contains (sub)-value of same type T

Next                                                    Suppose I wanted …
…   a program that processed lists of attributes
• Next we’ll do one-of                           •    Name (string)
•    Age (integer)
•    DOB (int-int-int)
• And then we’ll do recursive                    •    Address (string)
•    Height (float)
•    Alive (boolean)
•    Phone (int-int)
•    email (string)

Want to store them in a list. Can I ?

Constructing Datatypes                                  Suppose I wanted …
Attributes:                   type attrib =
type t = C1 of t1 | C2 of t2 | … | Cn of tn
• Name (string)                 Name of string
t is a new datatype.                                      • Age (integer)               | Age of int
A value of type t is either:                              • DOB (int-int-int)           | DOB of int*int*int
a value of type t1 placed in a box labeled C1       • Address (string)            | Address of string
Or    a value of type t2 placed in a box labeled C2
• Height (real)               | Height of float
Or    …
• Alive (boolean)             | Alive of bool
Or    a value of type tn placed in a box labeled Cn
• Phone (int-int)             | Phone of int*int
• email (string)              | Email of string;;

2
Creating Values                                                     One-of types
How to create values of type attrib ?                             • We’ve defined a “one-of” type named attrib
• Elements are one of:             type attrib =
# let a1 = Name “Joe”;;
val x : attrib = Name “Joe”                 type attrib =                                               Name of string
# let a2 = Height 5.83;;
– string,                       | Age of int
Name of string
val a2 : attrib = Height 5.83
| Age of int
– int,                          | DOB of int*int*int
# let year = 1977 ;;
| DOB of int*int*int      – int*int*int,                  | Address of string
val year : int = 1977
# let a3 = DOB (9,8,year) ;;                | Address of string                                       | Height of real
val a3 : attrib = DOB (9,8,1977)
– float,                        | Alive of bool
| Height of float
# let a_l = [a1;a2;a3];;
| Alive of bool
– bool …                        | Phone of int*int
val a3 : attrib list = …
| Phone of int*int                                           | Email of string;
| Email of string;;    • Can create uniform attrib lists

• Suppose I want a function to print attribs…

How to tell what’s in the box ?                                     match-with is an Expression
type attrib =                            match e with
match e   with
Name of string                           Name s -> e1
| Age of int                             | Age i -> e2                                  C1 x1   -> e1
| DOB of int*int*int                     | DOB (m,d,y) -> e3                          | C2 x2   -> e2
| Height of float
| Height h -> e5
| Alive of bool                                                                       | Cn xn   -> en
| Phone of int*int                       | Alive b -> e6
| Email of string;;                      | Phone (a,n) -> e7
| Email e -> e8
Pattern-match expression: check if e is of the form …               Type rules ?
• On match:                                                         • e1, e2,…,en must have same type
– value in box bound to pattern variable                         • Which is type of whole expression
– matching result expression is evaluated
• Simultaneously test and extract contents of box

Benefits of match-with                                              A similar problem in Java
match e   with        type   t =
C1 x1   -> e1         C1   of t1           if (o instof C1) {
| C2 x2   -> e2       | C2   of t2             x1 = (C1) o; s1                   Note similarity ...
| …                   | …                    } else if (o instof C2) {
match e   with
| Cn xn   -> en       | Cn   of tn             x2 = (C2) o; s2
C1 x1   -> e1
} else
| C2 x2   -> e2
1. Simultaneous test-extract-bind                                    ...                                  | …
} else if (o instof Cn) {
2. Compile-time checks for:                                                                               | Cn xn   -> en
xn = (Cn) o; sn
missed cases: OCaml warns if you miss a t value
redundant cases: OCaml warns if a case never
matches                                                                   Java doesn’t have match-with

3
if (o instof C1) {                                    if (o instof C1) {                           match o     with {
x1 = (C1) o; s1                                       x1 = (C1) o; s1                              C1 x1     -> { s1 }
} else if (o instof C2) {                             } else if (o instof C2) {                      C2 x2     -> { s2 }
x2 = (C2) o; s2                                       x2 = (C2) o; s2                              ...
} else                                                } else                                         Cn xn     -> { sn }
...                                                   ...                                          }
} else if (o instof Cn) {                             } else if (o instof Cn) {
xn = (Cn) o; sn                                       xn = (Cn) o; sn

match o   with {                                     type int_list =
C1 x1   -> { s1 }                                    Nil
C2 x2   -> { s2 }                                  | Cons of int * int_list
...
Cn xn   -> { sn }
}
1. Simultaneous test-extract-bind
2. Could have compile-time checks for:                Cons(1,Cons(2,Cons(3,Nil)))      Cons(2,Cons(3,Nil)) Cons(3,Nil)       Nil

missed cases                                                                   Cons            Cons        Cons
redundant cases?                                                                          1,          2,          3, Nil

Lists aren’t built-in !                               Some functions on Lists : Length
let rec len l =
datatype int_list =
Base pattern     match l with                       Base Expression
Nil                                                       Nil -> 0
| Cons of int * int_list                                  | Cons(h,t) -> 1 + (len t)
Ind pattern                                        Inductive Expression

Lists are a derived type: built using elegant core!
1. Each-of
let rec len l =                       let rec len l =
2. One-of                                               match l with                          match l with
3. Recursive                                              Nil -> 0                              Cons(_,t) => 1 + (len t)
| Cons(_,t) -> 1 + (len t)            | _ => 0
::     is just a pretty way to say “Cons”
Matches everything, no binding       Pattern-matching in order
[]     is just a pretty way to say “Nil”
- Must match with Nil

4
Some functions on Lists : Append                                     null, hd, tl are all functions …
let rec append l1 l2 =
Base pattern     match l1 with               Base Expression
[] -> l2                                          Bad OCaml style: More than aesthetics !
| h::t -> h::(append t l2);
Ind pattern                                   Inductive Expression
Pattern-matching better than test-extract:
• Ocaml checks all cases covered
• Find the right induction strategy
• Ocaml checks no redundant cases
– Base case: pattern + expression
• …at compile-time:
– Induction case: pattern + expression
– fewer errors (crashes) during execution
– get the bugs out ASAP!
• Well designed datatype gives strategy

Another Example: Calculator                                          Another Example: Calculator
We want an arithmetic calculator to                                  We want an arithmetic calculator to
evaluate expressions like:                                           evaluate expressions like:
• 4.0 + 2.9 = 6.9                                                    • 4.0 + 2.9 = 6.9
• 3.78 – 5.92 = -2.14                                                • 3.78 – 5.92 = -2.14
• (4.0 + 2.9) * (3.78 -5.92) = -14.766                               • (4.0 + 2.9) * (3.78 -5.92) = -14.766

Q: Whats a ML datatype for such expressions ?                        What’s a Ocaml function for evaluating such expressions ?

Random Art from Expressions
• In PA #2 you will answer these questions

• And you’ll make cool looking pics...

5

DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
 views: 5 posted: 3/23/2011 language: English pages: 5