A program is a sequence of expressions that are evaluated in order.
Every expression has a unique value and type.
We’ve seen primitive types and operators,
let (rec) expressions, function values and types, and product types (tuples).
Ocaml has a language for specifying types:
Structured data (tuples, lists) can be accessed through pattern matching.
reverse : 'a list -> 'a list
let rec reverse = function |  -> | h::t -> (reverse t) @ [h]
What if we evaluate
reverse [1; 2; …; 𝓃]?
reverse [2;3; …; 𝓃] @
reverse [3; …; 𝓃] @
reverse , @[𝓃]
[𝓃; …; 3; 2] @ 
[𝓃; …; 3] @ 
 @ [𝓃]
How would you do it in python?
def reverse(lst): = None res while lst != None: = cons(lst.head, res) res = lst.tail lst return res
We can express a similar algorithm in Ocaml:
let rec tail_rev lst res = match lst with |  -> res | h::t -> tail_rev t (h::res)
tail_rev 1::2::3:: 
≡ tail_rev 2::3:: 1::
≡ tail_rev 3:: 2::1::
≡ tail_rev  3::2::1::
≡ 3::2::1:: ≡ [3;2;1]
let rec tail_rev lst res = match lst with |  -> res| h::t -> tail_rev t (h::res)
tail_rev never returns control to recursive caller.
Functions defined this way are called tail recursive.
Since the stack frame doesn’t need to be restored, it can be re-used.
The compiled code is equivalent to the python algorithm.
def fact(n): = 1 res while n != 0: = n*res res = n-1 n return res
let rec tail_fact n res = if n = 0 then res else tail_fact (n-1) n*res
tail_fact 4 1
≡ tail_fact 3 4
≡ tail_fact 2 12
≡ tail_fact 1 24
res builds up or “accumulates” the result, so is often called an accumulator.
while loop can be transformed to tail recursion in this way.
Example: Write a tail-recursive definition for
length : 'a list -> int:
let rec tail_len lst len = match lst with |  -> len1)| _::t -> tail_len t (len+
What happens if we call
tail_len [1;2;3] 1337?
tail_rev with the wrong initial accumulator will yield an incorrect result.
Fortunately, since functions are values in OCaml, we can locally define the helper function for a tail-recursive implementation, e.g.:
let reverse lst = let rec tail_rev l acc = match l with |  -> acc | h::t -> tail_rev t (h::acc)in tail_rev lst 
Note: the OCaml
List module includes this function as
sumf: (int->int) -> int -> int from LabEx1:
let sumf f n = let rec sumhelp i res = if i = 0 then (res + (f 0)) else sumhelp (i-1) (res + (f i)) in sumhelp n 0
sumhelp is in the scope of the parameters to
sumf, it does not need to have the (loop-invariant) parameter
f as an argument.
Example: write tail-recursive version of
search_all : ’k -> (’k*’v) list -> ’v list:
let search_all key lst = let rec tail_sa l acc = match l with |  -> accif k=key then tail_sa t (v::acc) | (k,v)::t -> else tail_sa t acc in List.rev (tail_sa lst )