Recall Higher Order Functions
map (fun x -> x + 3) [1;2;3;4];;
Functions were treated like data and passed in
If funtions are data, we can also return them
let add3 x = x + 3 in
let sub3 x = x - 3 in
let lst = [add3;sub3] in
match lst with
[]->(fun x -> x * 3)
|h::_-> h;;
Recall anonymous syntactic sugar
let add3 x = x + 3;;
let add3 = (fun x -> x + 3);;
This works for multi-argument functions
let sum x y = x + y;;
let sum x = fun y -> x + y;;
let sum = fun x -> fun y -> x + y;;
This works for multi-argument functions
let sum x y = x + y;;
let sum x = fun y -> x + y;;
let sum = fun x -> fun y -> x + y;;
function now becomes: one input -> one output
Currying: process of converting a multi-argument function into a series of functions that each take one input
Currying: process of converting a multi-argument function into a series of functions that each take one input
Why?
let concat x y = x ^ y;;
concat "Hello " "world";;
concat "Hello " "earth";;
concat "Bye " "world";;
concat "Bye " "earth";;
let hello = concat "Hello ";;
let bye = concat "Bye ";;
hello "world"
hello "earth"
bye "world"
bye "earth"
Break Functions Down
let f x y z = (x + y) * z);;
f 3 4 6;;
let add = f 3 in
let mult = add 4 in
mult 6;;
Ultimately called a partial application
Some languages or functions only functions that take in one argument
let f x = (fun y -> x + y);;
let g = map f [1;2;3;4;5];;
map (fun h -> h 5) g;;
Technically this works either way in OCaml
Currying built in to OCaml How?
Remember everything is data in memory
let add x y = x + y;;
add 3 4;;
(* x and y are "local variables" *)
(* stored in a stack frame *)
Slight Issue
let partial = add 3;;
Where is 3 stored?
Closure: a tuple of an environment and a function (f,env)
Environment: mapping from variables to values
Evaluated at creation and immutable
let z = 4;;
let add x y = x + y;;
let g = add z;;
let z = 5;;
g 1;;
Recall this fib function
(* fib.ml *)
let rec fib n =
if n < 2 then 1 else (fib (n-1)) - (fib (n-2));;
Let's fix this
(* fib-1.ml *)
let rec fib n a b =
if n = 0 then a else fib (n-1) (a+b) a;;
Let's fix this
(* fib-1.ml *)
let rec fib n a b =
if n = 0 then a else fib (n-1) (a+b) a;;
Tail Position: the last thing computed before a function returns
Tail Recursion: Having the recursive call be in tail position
(Depends on the context: only at top level)