CSCI 2041

ADVANCED PROGRAMMING PRINCIPLES

Higher Order Functions:

Creating function values

Functions as values

Types we’ve seen so far, again:

Primitives: int, char, string, float, unit, bool, …
Product: t1 * t2, {f1 : t1 ; f2 : t2}
Union: 'a list, 'a option, boolExpr
Function: t1 -> t2

Programs in “functional” languages can create, pass and return functions as “first class” values

When would we use values of function type?

How do we construct values of function type?

Example: many searching tasks, such as

mem : 'a -> 'a list -> bool
find_all : 'a -> 'a list -> 'a list
assoc : 'a -> ('a * 'b) list -> 'b option

Require equality tests. But what makes two elements of type 'a equal?

find : ('a -> bool) -> 'a list -> bool
find_all : ('a -> bool) -> 'a list -> 'a list
assoc_by : ('a -> bool) -> ('a * 'b) list -> 'b option

How can we specify the function arguments?

Lambda expressions

From early history of computer science: λx → x+1

In Ocaml, fun param -> body:

find (fun x -> 3*x  < 17) l
find (fun a -> List.length a = 1) l

let mem x l = find ...

Closures

In the previous example, the function argument

(fun y -> x=y)

to find “remembers” what x was bound to in its scope.

Lambda expressions “capture” the bindings of names when they are defined

When a function references bindings from its enclosing scope but outside the scope of the call site it is called a “closure.”

let cmaker x =
  let y = x+7 in
    fun () -> y
let y = 3
let cl = cmaker 2
let now = cl () ;;
val cmaker : int -> unit -> int
val y : int = 3
val cl : unit -> int
val now : int = 9

Partial Application

Multi-argument functions in Ocaml are “curried”, e.g.:

(+) : int -> (int -> int)
(=) : 'a -> ('a -> bool)

“Partially” applying these functions creates new function values:

# (+) 2;;
- : int -> int
# (=) "The Doctor" ;;
- : string -> bool

Define mem in terms of find using partial application…

Combining Functions

let compose f g x = f (g x)

OCaml has a built-in operator |> similar to compose:

let (|>) x f = f x

This can be used to build “chains” of functions:

fun x -> x |> f |> g |> h

Also useful is swap:

let swap f x y = f y x

cs2041.org

// reveal.js plugins