Functional Programming with OCaml: Lecture Notes and Exercises, Study notes of Programming Languages

Material Type: Notes; Class: ORGNZTN PROGM LANG; Subject: Computer Science; University: University of Maryland; Term: Unknown 1989;

Typology: Study notes

Pre 2010

Uploaded on 02/13/2009

koofers-user-dao
koofers-user-dao 🇺🇸

5

(1)

10 documents

1 / 32

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CMSC 330: Organization of
Programming Languages
Functional Programming with OCaml
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20

Partial preview of the text

Download Functional Programming with OCaml: Lecture Notes and Exercises and more Study notes Programming Languages in PDF only on Docsity!

CMSC 330: Organization of

Programming Languages

Functional Programming with OCaml

Review

• Recursion is how all looping is done

• OCaml can easily pass and return functions

Nested Functions

• In OCaml, you can define functions anywhere

– Even inside of other functions

let pick_one n = if n > 0 then (fun x -> x + 1) else (fun x -> x - 1) (pick_one -5) 6 (* returns 5 *)

let sum l = fold ((fun (a, x) -> a + x), 0, l)

Nested Functions (cont’d)

• You can also use let to define functions inside of

other functions

let sum l = let add (a, x) = a + x in fold (add, 0, l)

let pick_one n = let add_one x = x + 1 in let sub_one x = x - 1 in if n > 0 then add_one else sub_one

Consider the Call Stack Again

• How does add know the value of n?

– Read it off the stack?

  • (^) Possible, but the semantics are wrong (see above)

– OCaml uses static scoping like C, C++, Java, and Ruby

let addN (n, l) =

map (add, l)

let map (f, n) = match n with [] -> [] | (h::t) -> (f h)::(map (f, t))

addN (3, [1; 2; 3])

let add x = n + x in

n 3

l

f

n

x 1

Static Scoping

• In static or lexical scoping , (nonlocal) names

refer to their nearest binding in the program text

– Going from inner to outer scope

– C example:

– In our example, add accesses addN’s n

int x; void f() { x = 3; } void g() { char *x = "hello"; f(); }

Refers to the x at file scope – that’s

the nearest x going from inner scope

to outer scope in the source code

Environments and Closures

• An environment is a mapping from variable

names to values

– Just like a stack frame

• A closure is a pair (f, e) consisting of function

code f and an environment e

• When you invoke a closure, f is evaluated using

e to look up variable bindings

Example

let add x = (fun y -> x + y)

(add 3) 4 4 ^^3 +^4 7

Yet Another Example

let twice (n, y) = let f x = x + n in f (f y)

twice (3, 4) ( 4) 7 10

Still Another Example

let add x = (fun y -> (fun z -> x + y + z))

(((add 1) 2) 3) (( 2) 3) ( 3) 1+2+

Curried Functions in OCaml

• OCaml has a really simple syntax for currying

– This is identical to all of the following:

• Thus:

– add has type int -> (int -> int)

– add 3 has type int -> int

  • (^) The return of add x evaluated with x = 3
  • (^) add 3 is a function that adds 3 to its argument
  • (^) (add 3) 4 = 7

• This works for any number of arguments

let add x y = x + y

let add = (fun x -> (fun y -> x + y)) let add = (fun x y -> x + y) let add x = (fun y -> x+y)

Curried Functions in OCaml (cont’d)

• Because currying is so common, OCaml uses

the following conventions:

– -> associates to the right

  • (^) Thus int -> int -> int is the same as
  • (^) int -> (int -> int)

– function application associates to the left

  • (^) Thus add 3 4 is the same as
  • (^) (add 3) 4

Currying and the map Function

• Examples

let negate x = -x

map negate [1; 2; 3] (* returns [-1; -2; -3 ] *)

let negate_list = map negate

negate_list [-1; -2; -3]

let sum_pairs_list = map (fun (a, b) -> a + b)

sum_pairs_list [(1, 2); (3, 4)] (* [3; 7] *)

• What's the type of this form of map?

let rec map f l = match l with [] -> [] | (h::t) -> (f h)::(map f t)

map : ('a -> 'b) -> 'a list -> 'b list

Currying and the fold Function

let rec fold f a l = match l with [] -> a | (h::t) -> fold f (f a h) t

let add x y = x + y

fold add 0 [1; 2; 3]

let sum = fold add 0

sum [1; 2; 3]

let next n _ = n + 1

let length = fold next 0 (* warning: not polymorphic *)

length [4; 5; 6; 7]

• What's the type of this form of fold?

fold : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a