Lecture 06
Let Patterns, Tail Recursion, Exceptions
Programming Languages
UW CSE 341 - Winter 2021
Updates 2021-01-22
Pattern Matching
& let Bindings
let binds with patterns
let binding patterns
Let Expressions : Local Variable Binding
Syntax: let p = e1 in e2
Let Expressions : Local Variable Binding
Syntax: let p = e1 in e2
Type Checking
Let Expressions : Local Variable Binding
Syntax: let p = e1 in e2
Evaluation
let binding patterns : really for “each of”
(* very bad style! *)
let first xs =
let x :: _ = xs in
x
let get oa =
let Some a = oa in
a
let binding patterns
Syntax: let [rec] f (p1 : t1) … (pN : tN) : t = e1 in e2
let binding patterns
(* still not great style,
but shows patterns *)
type date = int * (int * int)
let get_day (d, (_, _)) = d
let get_month (_, (m, _)) = m
let get_year (_, (_, y)) = y
let binding patterns
(* still not great style,
but shows patterns *)
type date = int * (int * int)
let get_day (d, (_, _)) = d
let get_month (_, (m, _)) = m
let get_year (_, (_, y)) = y
(* a bit better, but patterns overkill *)
type date =
{ day : int
; month : int
; year : int }
let get_day {day = d; month = _; year = _} = d
let get_month {day = _; month = m; year = _} = m
let get_year {day = _; month = _; year = y} = y
Nesting Patterns
let rec zip3 xs ys zs =
match xs, ys, zs with
| [], [], [] ->
[]
| x :: xs', y :: ys', z :: zs' ->
(x, y, z) :: zip3 xs' ys' zs'
| _, _, _ ->
failwith "zip3: bogus”
let unzip3 trips =
let rec loop xyzs (xs, ys, zs) =
match xyzs with
| [] ->
(xs, ys, zs)
| (x, y, z) :: rest ->
loop rest (x :: xs, y :: ys, z :: zs)
in
loop trips ([], [], [])
Tail Recursion
Recursion
Call Stacks
While a program runs, a call stack tracks function calls “in progress”
Each stack frame records:
With recursion, same function may have many active stack frames
Example
Example
Example
Do we ALWAYS need a stack frame? (Hint: No.)
How OCaml really executes last
Moral of Tail Recursion
Always use Tail Recursion?
Definition of a Tail Call
A tail call is a function call in tail position. An expression is in tail position when:
Exceptions
Exceptions
Exception bindings declare new kinds of exception:
raise expressions can throw an exception:
try … with … expressions can catch exceptions
exception Bogus
exception BadNum of int
raise Bogus
raise (BadNum 1)
try (* ... *) with Bogus -> 0
try (* ... *) with BadNum n -> n
Exceptions as “One Big Variant”