1 of 116

1

Programming Languages and Compilers (CS 421)

Talia Ringer (they/them)

4218 SC, UIUC

https://courses.grainger.illinois.edu/cs421/fa2023/

Based heavily on slides by Elsa Gunter, which were based in part on slides by Mattox Beckman, as updated by Vikram Adve and Gul Agha

2 of 116

  • On Tuesday, we saw some great language features, like tuples, patterns, pattern matching, and partial function application.
  • We also saw how currying gets us between a function that takes a tuple as an argument, and a function that takes its arguments one at a time.
  • Finally, we saw how closures map from patterns.
  • Today, we will briefly look at recursion coupled with pattern matching in OCaml.
  • We will then finally get to evaluating expressions in OCaml!

Objectives for Today

2

3 of 116

  • On Tuesday, we saw some great language features, like tuples, patterns, pattern matching, and partial function application.
  • We also saw how currying gets us between a function that takes a tuple as an argument, and a function that takes its arguments one at a time.
  • Finally, we saw how closures map from patterns.
  • Today, we will briefly look at recursion coupled with pattern matching in OCaml.
  • We will then finally get to evaluating expressions in OCaml!

Objectives for Today

3

4 of 116

4

Questions from last time?

5 of 116

5

Intro to Recursion in OCaml

6 of 116

Recursive Functions

# (* rec needed for recursive function declarations *)

let rec factorial n =

if n = 0 then

1

else

n * factorial (n - 1);;

val factorial : int -> int = <fun>

# factorial 5;;

- : int = 120

*

6

Recursion in OCaml

7 of 116

Recursive Functions

# (* rec needed for recursive function declarations *)

let rec factorial n =

if n = 0 then

1

else

n * factorial (n - 1);;

val factorial : int -> int = <fun>

# factorial 5;;

- : int = 120

*

7

Recursion in OCaml

8 of 116

Recursive Functions

# (* rec needed for recursive function declarations *)

let rec factorial n =

if n = 0 then

1

else

n * factorial (n - 1);;

val factorial : int -> int = <fun>

# factorial 5;;

- : int = 120

*

8

Recursion in OCaml

9 of 116

Recursive Functions

# (* rec needed for recursive function declarations *)

let rec factorial n =

if n = 0 then

1

else

n * factorial (n - 1);;

val factorial : int -> int = <fun>

# factorial 5;;

- : int = 120

*

9

Recursion in OCaml

10 of 116

Recursive Functions

# (* rec needed for recursive function declarations *)

let rec factorial n =

if n = 0 then

1

else

n * factorial (n - 1);;

val factorial : int -> int = <fun>

# factorial 5;;

- : int = 120

*

10

Recursion in OCaml

Without the rec keyword, we’d get “Error: Unbound value factorial.”

11 of 116

Pattern Matching and Recursion

Compute n2 recursively using:

n2 = (2 * n - 1) + (n - 1)2

# let rec sq n = (* rec for recursion *)

match n with (* pattern matching for cases *)

| 0 -> 0 (* base case *)

| n -> (2 * n -1) + sq (n -1);; (* recursive case *)

val sq : int -> int = <fun>

# sq 3;;

  • : int = 9

11

Recursion in OCaml

12 of 116

Pattern Matching and Recursion

Compute n2 recursively using:

n2 = (2 * n - 1) + (n - 1)2

# let rec sq n = (* rec for recursion *)

match n with (* pattern matching for cases *)

| 0 -> 0 (* base case *)

| n -> (2 * n -1) + sq (n -1);; (* recursive case *)

val sq : int -> int = <fun>

# sq 3;;

  • : int = 9

12

Recursion in OCaml

13 of 116

Pattern Matching and Recursion

Compute n2 recursively using:

n2 = (2 * n - 1) + (n - 1)2

# let rec sq n = (* rec for recursion *)

match n with (* pattern matching for cases *)

| 0 -> 0 (* base case *)

| n -> (2 * n -1) + sq (n -1);; (* recursive case *)

val sq : int -> int = <fun>

# sq 3;;

  • : int = 9

13

Recursion in OCaml

14 of 116

Pattern Matching and Recursion

Compute n2 recursively using:

n2 = (2 * n - 1) + (n - 1)2

# let rec sq n = (* rec for recursion *)

match n with (* pattern matching for cases *)

| 0 -> 0 (* base case *)

| n -> (2 * n -1) + sq (n -1);; (* recursive case *)

val sq : int -> int = <fun>

# sq 3;;

  • : int = 9

14

Recursion in OCaml

15 of 116

Pattern Matching and Recursion

Compute n2 recursively using:

n2 = (2 * n - 1) + (n - 1)2

# let rec sq n = (* rec for recursion *)

match n with (* pattern matching for cases *)

| 0 -> 0 (* base case *)

| n -> (2 * n -1) + sq (n -1);; (* recursive case *)

val sq : int -> int = <fun>

# sq 3;;

  • : int = 9

15

Recursion in OCaml

16 of 116

Pattern Matching and Recursion

Compute n2 recursively using:

n2 = (2 * n - 1) + (n - 1)2

# let rec sq n = (* rec for recursion *)

match n with (* pattern matching for cases *)

| 0 -> 0 (* base case *)

| n -> (2 * n -1) + sq (n -1);; (* recursive case *)

val sq : int -> int = <fun>

# sq 3;;

  • : int = 9

16

Recursion in OCaml

17 of 116

Pattern Matching and Recursion

Compute n2 recursively using:

n2 = (2 * n - 1) + (n - 1)2

# let rec sq n = (* rec for recursion *)

match n with (* pattern matching for cases *)

| 0 -> 0 (* base case *)

| n -> (2 * n -1) + sq (n -1);; (* recursive case *)

val sq : int -> int = <fun>

# sq 3;;

  • : int = 9

17

Aside: Recursion and induction are deeply, beautifully related. (Discussed in thesis, if curious.)

Recursion in OCaml

18 of 116

Pattern Matching and Recursion

Compute n2 recursively using:

n2 = (2 * n - 1) + (n - 1)2

# let rec sq n = (* rec for recursion *)

match n with (* pattern matching for cases *)

| 0 -> 0 (* base case *)

| n -> (2 * n -1) + sq (n -1);; (* recursive case *)

val sq : int -> int = <fun>

# sq 3;;

  • : int = 9

18

Aside: Recursion and induction are deeply, beautifully related. (Discussed in thesis, if curious.)

Recursion in OCaml

19 of 116

Pattern Matching and Recursion

Compute n2 recursively using:

n2 = (2 * n - 1) + (n - 1)2

# let rec sq n = (* rec for recursion *)

match n with (* pattern matching for cases *)

| 0 -> 0 (* base case *)

| n -> (2 * n -1) + sq (n -1);; (* recursive case *)

val sq : int -> int = <fun>

# sq 3;;

  • : int = 9

19

Aside: Recursion and induction are deeply, beautifully related. (Discussed in thesis, if curious.)

Recursion in OCaml

20 of 116

Pattern Matching and Recursion

Compute n2 recursively using:

n2 = (2 * n - 1) + (n - 1)2

# let rec sq n = (* rec for recursion *)

match n with (* pattern matching for cases *)

| 0 -> 0 (* base case *)

| n -> (2 * n -1) + sq (n -1);; (* inductive case *)

val sq : int -> int = <fun>

# sq 3;;

  • : int = 9

20

Aside: Recursion and induction are deeply, beautifully related. (Discussed in thesis, if curious.)

Recursion in OCaml

21 of 116

Pattern Matching and Recursion

Compute n2 recursively using:

n2 = (2 * n - 1) + (n - 1)2

# let rec sq n = (* rec for recursion *)

match n with (* pattern matching for cases *)

| 0 -> 0 (* base case *)

| n -> (2 * n -1) + sq (n -1);; (* inductive case *)

val sq : int -> int = <fun>

# sq 3;;

  • : int = 9

21

Aside: Recursion and induction are deeply, beautifully related. (Discussed in thesis, if curious.)

Recursion in OCaml

22 of 116

Pattern Matching and Recursion

Compute n2 recursively using:

n2 = (2 * n - 1) + (n - 1)2

# let rec sq n = (* rec for recursion *)

match n with (* pattern matching for cases *)

| 0 -> 0 (* base case *)

| n -> (2 * n -1) + sq (n -1);; (* inductive case *)

val sq : int -> int = <fun>

# sq 3;;

  • : int = 9

22

Aside: Recursion and induction are deeply, beautifully related. (Discussed in thesis, if curious.)

Recursion in OCaml

23 of 116

23

Questions so far?

Recursion in OCaml

24 of 116

24

More Recursion Next Week

Recursion in OCaml

25 of 116

25

Evaluating OCaml Programs

26 of 116

Evaluating declarations

  • Evaluation uses an environment ρ
  • To evaluate a (simple) declaration let x = e
    • Evaluate expression e in ρ to value v
    • Update ρ with x v: {x → v} + ρ
  • Update: ρ1+ ρ2 has all the bindings in ρ1 and all those in ρ2 that are not rebound in ρ1

{x → 2, y → 3, a → “hi”} + {y → 100, b → 6} =

{x → 2, y → 3, a → “hi”, b → 6}

*

26

Evaluation

27 of 116

Evaluating declarations

  • Evaluation uses an environment ρ
  • To evaluate a (simple) declaration let x = e
    • Evaluate expression e in ρ to value v
    • Update ρ with x v: {x → v} + ρ
  • Update: ρ1+ ρ2 has all the bindings in ρ1 and all those in ρ2 that are not rebound in ρ1

{x → 2, y → 3, a → “hi”} + {y → 100, b → 6} =

{x → 2, y → 3, a → “hi”, b → 6}

*

27

Evaluation

28 of 116

Evaluating declarations

  • Evaluation uses an environment ρ
  • To evaluate a (simple) declaration let x = e
    • Evaluate expression e in ρ to value v
    • Update ρ with x v: {x → v} + ρ
  • Update: ρ1+ ρ2 has all the bindings in ρ1 and all those in ρ2 that are not rebound in ρ1

{x → 2, y → 3, a → “hi”} + {y → 100, b → 6} =

{x → 2, y → 3, a → “hi”, b → 6}

*

28

Evaluation

29 of 116

Evaluating declarations

  • Evaluation uses an environment ρ
  • To evaluate a (simple) declaration let x = e
    • Evaluate expression e in ρ to value v
    • Update ρ with x v: {x → v} + ρ
  • Update: ρ1+ ρ2 has all the bindings in ρ1 and all those in ρ2 that are not rebound in ρ1

{x → 2, y → 3, a → “hi”} + {y → 100, b → 6} =

{x → 2, y → 3, a → “hi”, b → 6}

*

29

Evaluation

30 of 116

Evaluating declarations

  • Evaluation uses an environment ρ
  • To evaluate a (simple) declaration let x = e
    • Evaluate expression e in ρ to value v
    • Update ρ with x v: {x → v} + ρ
  • Update: ρ1+ ρ2 has all the bindings in ρ1 and all those in ρ2 that are not rebound in ρ1

{x → 2, y → 3, a → “hi”} + {y → 100, b → 6} =

{x → 2, y → 3, a → “hi”, b → 6}

*

30

Evaluation

31 of 116

Evaluating expressions in OCaml

  • Evaluation takes expression e and an environment ρ, and evaluates e in ρ to some value v:
    • Eval (e , ρ) => v
  • A constant c evaluates to itself, including primitive operators like + and =
    • Eval (c , ρ) => Val c
  • To evaluate a variable v, look it up in ρ:
    • Eval (v, ρ) => Val (ρ(v))

*

31

Evaluation

32 of 116

Evaluating expressions in OCaml

  • Evaluation takes expression e and an environment ρ, and evaluates e in ρ to some value v:
    • Eval (e , ρ) => v
  • A constant c evaluates to itself, including primitive operators like + and =
    • Eval (c , ρ) => Val c
  • To evaluate a variable v, look it up in ρ:
    • Eval (v, ρ) => Val (ρ(v))

*

32

Evaluation

33 of 116

Evaluating expressions in OCaml

  • Evaluation takes expression e and an environment ρ, and evaluates e in ρ to some value v:
    • Eval (e , ρ) => v
  • A constant c evaluates to itself, including primitive operators like + and =
    • Eval (c , ρ) => Val c
  • To evaluate a variable v, look it up in ρ:
    • Eval (v, ρ) => Val (ρ(v))

*

33

Evaluation

34 of 116

Evaluating expressions in OCaml

  • Evaluation takes expression e and an environment ρ, and evaluates e in ρ to some value v:
    • Eval (e , ρ) => v
  • A constant c evaluates to itself, including primitive operators like + and =
    • Eval (c , ρ) => Val c
  • To evaluate a variable v, look it up in ρ:
    • Eval (v, ρ) => Val (ρ(v))

*

34

Evaluation

35 of 116

Evaluating expressions in OCaml

  • Evaluation takes expression e and an environment ρ, and evaluates e in ρ to some value v:
    • Eval (e , ρ) => v
  • A constant c evaluates to itself, including primitive operators like + and =
    • Eval (c , ρ) => Val c
  • To evaluate a variable v, look it up in ρ:
    • Eval (v, ρ) => Val (ρ(v))

*

35

Evaluation

36 of 116

36

Questions so far?

Evaluation

37 of 116

Evaluating expressions in OCaml

  • Evaluation takes expression e and an environment ρ, and evaluates e in ρ to some value v:
    • Eval (e , ρ) => v
  • We define evaluation one small step at a time. So when evaluating an expression e requires recursively evaluating some subexpression, we may write something like:
    • Eval (e , ρ) => Eval (e’ , ρ’)

for subexpression e’ and updated environment ρ’.

*

37

Evaluation

38 of 116

Evaluating expressions in OCaml

  • Evaluation takes expression e and an environment ρ, and evaluates e in ρ to some value v:
    • Eval (e , ρ) => v
  • We define evaluation one small step at a time. So when evaluating an expression e requires recursively evaluating some subexpression, we may write something like:
    • Eval (e , ρ) => Eval (e’ , ρ’)

for subexpression e’ and updated environment ρ’

*

38

Evaluation

39 of 116

Evaluating expressions in OCaml

  • Evaluation takes expression e and an environment ρ, and evaluates e in ρ to some value v:
    • Eval (e , ρ) => v
  • We define evaluation one small step at a time. So when evaluating an expression e requires recursively evaluating some subexpression, we may write something like:
    • Eval (e , ρ) => Eval (e’ , ρ’)

for subexpression e’ and updated environment ρ’

*

39

Evaluation

This gives us an algorithm to implement an interpreter!

40 of 116

Evaluating expressions in OCaml

  • To evaluate a tuple (e1 , … , en):
    • Evaluate each ei to vi, right to left for OCaml
    • Then make value (v1 , … , vn)
    • Eval((e1 , … , en), ρ) =>

Eval((e1 , … , Eval (en, ρ)), ρ)

    • Eval((e1 , … , ei, Val vi+1 , … , Val vn), ρ) =>

Eval((e1 , … , Eval(ei, ρ), Val vi+1 , … , Val vn), ρ)

    • Eval((Val v1 , … , Val vn) , ρ) =>

Val (v1 , … , vn)

*

40

Evaluation

41 of 116

Evaluating expressions in OCaml

  • To evaluate a tuple (e1 , … , en):
    • Evaluate each ei to vi, right to left for OCaml
    • Then make value (v1 , … , vn)
    • Eval((e1 , … , en), ρ) =>

Eval((e1 , … , Eval (en, ρ)), ρ)

    • Eval((e1 , … , ei, Val vi+1 , … , Val vn), ρ) =>

Eval((e1 , … , Eval(ei, ρ), Val vi+1 , … , Val vn), ρ)

    • Eval((Val v1 , … , Val vn) , ρ) =>

Val (v1 , … , vn)

*

41

Evaluation

42 of 116

Evaluating expressions in OCaml

  • To evaluate a tuple (e1 , … , en):
    • Evaluate each ei to vi, right to left for OCaml
    • Then make value (v1 , … , vn)
    • Eval((e1 , … , en), ρ) =>

Eval((e1 , … , Eval (en, ρ)), ρ)

    • Eval((e1 , … , ei, Val vi+1 , … , Val vn), ρ) =>

Eval((e1 , … , Eval(ei, ρ), Val vi+1 , … , Val vn), ρ)

    • Eval((Val v1 , … , Val vn) , ρ) =>

Val (v1 , … , vn)

*

42

Evaluation

43 of 116

Evaluating expressions in OCaml

  • To evaluate a tuple (e1 , … , en):
    • Evaluate each ei to vi, right to left for OCaml
    • Then make value (v1 , … , vn)
    • Eval((e1 , … , en), ρ) =>

Eval((e1 , … , Eval (en, ρ)), ρ)

    • Eval((e1 , … , ei, Val vi+1 , … , Val vn), ρ) =>

Eval((e1 , … , Eval(ei, ρ), Val vi+1 , … , Val vn), ρ)

    • Eval((Val v1 , … , Val vn) , ρ) =>

Val (v1 , … , vn)

*

43

Evaluation

44 of 116

Evaluating expressions in OCaml

  • To evaluate a tuple (e1 , … , en):
    • Evaluate each ei to vi, right to left for OCaml
    • Then make value (v1 , … , vn)
    • Eval((e1 , … , en), ρ) =>

Eval((e1 , … , Eval (en, ρ)), ρ)

    • Eval((e1 , … , ei, Val vi+1 , … , Val vn), ρ) =>

Eval((e1 , … , Eval(ei, ρ), Val vi+1 , … , Val vn), ρ)

    • Eval((Val v1 , … , Val vn) , ρ) =>

Val (v1 , … , vn)

*

44

Evaluation

45 of 116

Evaluating expressions in OCaml

  • To evaluate a tuple (e1 , … , en):
    • Evaluate each ei to vi, right to left for OCaml
    • Then make value (v1 , … , vn)
    • Eval((e1 , … , en), ρ) =>

Eval((e1 , … , Eval (en, ρ)), ρ)

    • Eval((e1 , … , ei, Val vi+1 , … , Val vn), ρ) =>

Eval((e1 , … , Eval(ei, ρ), Val vi+1 , … , Val vn), ρ)

    • Eval((Val v1 , … , Val vn) , ρ) =>

Val (v1 , … , vn)

*

45

Evaluation

46 of 116

46

Questions so far?

Evaluation

47 of 116

Evaluating expressions in OCaml

  • To evaluate uses of +, - , etc., eval args, then do operation ⦿ (+, -, *, +., …):
    • Eval(e1⦿ e2, ρ) =>

Eval(e1⦿ Eval(e2, ρ), ρ))

    • Eval(e1⦿ Val e2, ρ) =>

Eval(Eval(e1, ρ) ⦿ Val v2, ρ))

    • Eval(Val v1⦿ Val v2) =>

Val (v1⦿ v2)

  • Function expression evaluates to its closure
    • Eval (fun x -> e, ρ) => Val < x -> e, ρ>

*

47

Evaluation

48 of 116

Evaluating expressions in OCaml

  • To evaluate uses of +, - , etc., eval args, then do operation ⦿ (+, -, *, +., …):
    • Eval(e1⦿ e2, ρ) =>

Eval(e1⦿ Eval(e2, ρ), ρ))

    • Eval(e1⦿ Val e2, ρ) =>

Eval(Eval(e1, ρ) ⦿ Val v2, ρ))

    • Eval(Val v1⦿ Val v2) =>

Val (v1⦿ v2)

  • Function expression evaluates to its closure
    • Eval (fun x -> e, ρ) => Val < x -> e, ρ>

*

48

Evaluation

49 of 116

Evaluating expressions in OCaml

  • To evaluate uses of +, - , etc., eval args, then do operation ⦿ (+, -, *, +., …):
    • Eval(e1⦿ e2, ρ) =>

Eval(e1⦿ Eval(e2, ρ), ρ))

    • Eval(e1⦿ Val e2, ρ) =>

Eval(Eval(e1, ρ) ⦿ Val v2, ρ))

    • Eval(Val v1⦿ Val v2) =>

Val (v1⦿ v2)

  • Function expression evaluates to its closure
    • Eval (fun x -> e, ρ) => Val < x -> e, ρ>

*

49

Evaluation

50 of 116

Evaluating expressions in OCaml

  • To evaluate uses of +, - , etc., eval args, then do operation ⦿ (+, -, *, +., …):
    • Eval(e1⦿ e2, ρ) =>

Eval(e1⦿ Eval(e2, ρ), ρ))

    • Eval(e1⦿ Val e2, ρ) =>

Eval(Eval(e1, ρ) ⦿ Val v2, ρ))

    • Eval(Val v1⦿ Val v2, ρ) =>

Val (v1⦿ v2)

  • Function expression evaluates to its closure
    • Eval (fun x -> e, ρ) => Val < x -> e, ρ>

*

50

Evaluation

51 of 116

Evaluating expressions in OCaml

  • To evaluate uses of +, - , etc., eval args, then do operation ⦿ (+, -, *, +., …):
    • Eval(e1⦿ e2, ρ) =>

Eval(e1⦿ Eval(e2, ρ), ρ))

    • Eval(e1⦿ Val e2, ρ) =>

Eval(Eval(e1, ρ) ⦿ Val v2, ρ))

    • Eval(Val v1⦿ Val v2) =>

Val (v1⦿ v2)

  • Function expression evaluates to its closure
    • Eval (fun x -> e, ρ) => Val < x -> e, ρ>

*

51

Evaluation

52 of 116

Evaluating expressions in OCaml

  • To evaluate a local declaration:

let x = e1 in e2

    • Eval e1 to v, then eval e2 using {x → v} + ρ
    • Eval(let x = e1 in e2, ρ) => Eval(let x = Eval(e1, ρ) in e2, ρ)
    • Eval(let x = Val v in e2, ρ) => Eval(e2, {x → v} + ρ)

*

52

Evaluation

53 of 116

Evaluating expressions in OCaml

  • To evaluate a local declaration:

let x = e1 in e2

    • Eval e1 to v, then eval e2 using {x → v} + ρ
    • Eval(let x = e1 in e2, ρ) => Eval(let x = Eval(e1, ρ) in e2, ρ)
    • Eval(let x = Val v in e2, ρ) => Eval(e2, {x → v} + ρ)

*

53

Evaluation

54 of 116

Evaluating expressions in OCaml

  • To evaluate a local declaration:

let x = e1 in e2

    • Eval e1 to v, then eval e2 using {x → v} + ρ
    • Eval(let x = e1 in e2, ρ) => Eval(let x = Eval(e1, ρ) in e2, ρ)
    • Eval(let x = Val v in e2, ρ) => Eval(e2, {x → v} + ρ)

*

54

Evaluation

55 of 116

Evaluating expressions in OCaml

  • To evaluate a conditional expression:

if b then e1 else e2

    • Evaluate b to a value v
    • If v is true, evaluate e1
    • If v is false, evaluate e2
    • Eval(if b then e1 else e2, ρ) => Eval(if Eval(b, ρ) then e1 else e2, ρ)
    • Eval(if Val true then e1 else e2, ρ) => Eval(e1, ρ)
    • Eval(if Val false then e1 else e2, ρ) => Eval(e2, ρ)

*

55

Evaluation

56 of 116

Evaluating expressions in OCaml

  • To evaluate a conditional expression:

if b then e1 else e2

    • Evaluate b to a value v
    • If v is true, evaluate e1
    • If v is false, evaluate e2
    • Eval(if b then e1 else e2, ρ) => Eval(if Eval(b, ρ) then e1 else e2, ρ)
    • Eval(if Val true then e1 else e2, ρ) => Eval(e1, ρ)
    • Eval(if Val false then e1 else e2, ρ) => Eval(e2, ρ)

*

56

Evaluation

57 of 116

Evaluating expressions in OCaml

  • To evaluate a conditional expression:

if b then e1 else e2

    • Evaluate b to a value v
    • If v is true, evaluate e1
    • If v is false, evaluate e2
    • Eval(if b then e1 else e2, ρ) => Eval(if Eval(b, ρ) then e1 else e2, ρ)
    • Eval(if Val true then e1 else e2, ρ) => Eval(e1, ρ)
    • Eval(if Val false then e1 else e2, ρ) => Eval(e2, ρ)

*

57

Evaluation

58 of 116

Evaluating expressions in OCaml

  • To evaluate a conditional expression:

if b then e1 else e2

    • Evaluate b to a value v
    • If v is true, evaluate e1
    • If v is false, evaluate e2
    • Eval(if b then e1 else e2, ρ) => Eval(if Eval(b, ρ) then e1 else e2, ρ)
    • Eval(if Val true then e1 else e2, ρ) => Eval(e1, ρ)
    • Eval(if Val false then e1 else e2, ρ) => Eval(e2, ρ)

*

58

Evaluation

59 of 116

Evaluating expressions in OCaml

  • To evaluate a conditional expression:

if b then e1 else e2

    • Evaluate b to a value v
    • If v is true, evaluate e1
    • If v is false, evaluate e2
    • Eval(if b then e1 else e2, ρ) => Eval(if Eval(b, ρ) then e1 else e2, ρ)
    • Eval(if Val true then e1 else e2, ρ) => Eval(e1, ρ)
    • Eval(if Val false then e1 else e2, ρ) => Eval(e2, ρ)

*

59

Evaluation

60 of 116

Evaluating expressions in OCaml

  • To evaluate a conditional expression:

if b then e1 else e2

    • Evaluate b to a value v
    • If v is true, evaluate e1
    • If v is false, evaluate e2
    • Eval(if b then e1 else e2, ρ) => Eval(if Eval(b, ρ) then e1 else e2, ρ)
    • Eval(if Val true then e1 else e2, ρ) => Eval(e1, ρ)
    • Eval(if Val false then e1 else e2, ρ) => Eval(e2, ρ)

*

60

Evaluation

61 of 116

61

Questions so far?

Evaluation

62 of 116

Evaluation of Application with Closures

  • Given application expression f e
    • In OCaml, evaluate e to value v
    • In environment ρ, evaluate f to <(x1,…,xn) → b, ρ’>
    • Evaluate body b in {x1 → v1,…, xn →vn} + ρ’
    • Eval(f e, ρ) => Eval(f (Eval(e, ρ)), ρ)
    • Eval(f (Val v), ρ) => Eval((Eval(f, ρ)) (Val v), ρ)
    • Eval((Val<(x1 , … , xn)→b, ρ’>)(Val(v1 , … , vn)), ρ) => Eval(b, {x1→v1 , … , xn→vn} + ρ’)

*

62

Evaluation

63 of 116

Evaluation of Application with Closures

  • Given application expression f e
    • In OCaml, evaluate e to value v
    • In environment ρ, evaluate f to <(x1,…,xn) → b, ρ’>
    • Evaluate body b in {x1 → v1,…, xn →vn} + ρ’
    • Eval(f e, ρ) => Eval(f (Eval(e, ρ)), ρ)
    • Eval(f (Val v), ρ) => Eval((Eval(f, ρ)) (Val v), ρ)
    • Eval((Val<(x1 , … , xn)→b, ρ’>)(Val(v1 , … , vn)), ρ) => Eval(b, {x1→v1 , … , xn→vn} + ρ’)

*

63

Evaluation

64 of 116

Evaluation of Application with Closures

  • Given application expression f e
    • In OCaml, evaluate e to value v
    • In environment ρ, evaluate f to <(x1,…,xn) → b, ρ’>
    • Evaluate body b in {x1 → v1,…, xn →vn} + ρ’
    • Eval(f e, ρ) => Eval(f (Eval(e, ρ)), ρ)
    • Eval(f (Val v), ρ) => Eval((Eval(f, ρ)) (Val v), ρ)
    • Eval((Val<(x1 , … , xn)→b, ρ’>)(Val(v1 , … , vn)), ρ) => Eval(b, {x1→v1 , … , xn→vn} + ρ’)

*

64

Evaluation

65 of 116

Evaluation of Application with Closures

  • Given application expression f e
    • In OCaml, evaluate e to value v
    • In environment ρ, evaluate f to <(x1,…,xn) → b, ρ’>
    • Evaluate body b in {x1 → v1,…, xn →vn} + ρ’
    • Eval(f e, ρ) => Eval(f (Eval(e, ρ)), ρ)
    • Eval(f (Val v), ρ) => Eval((Eval(f, ρ)) (Val v), ρ)
    • Eval((Val<(x1 , … , xn)→b, ρ’>)(Val(v1 , … , vn)), ρ) => Eval(b, {x1→v1 , … , xn→vn} + ρ’)

*

65

Evaluation

66 of 116

Evaluation of Application with Closures

  • Given application expression f e
    • In OCaml, evaluate e to value v
    • In environment ρ, evaluate f to <(x1,…,xn) → b, ρ’>
    • Evaluate body b in {x1 → v1,…, xn →vn} + ρ’
    • Eval(f e, ρ) => Eval(f (Eval(e, ρ)), ρ)
    • Eval(f (Val v), ρ) => Eval((Eval(f, ρ)) (Val v), ρ)
    • Eval((Val<(x1 , … , xn)→b, ρ’>)(Val(v1 , … , vn)), ρ) => Eval(b, {x1→v1 , … , xn→vn} + ρ’)

*

66

Evaluation

67 of 116

Evaluation of Application with Closures

  • Given application expression f e
    • In OCaml, evaluate e to value v
    • In environment ρ, evaluate f to <(x1,…,xn) → b, ρ’>
    • Evaluate body b in {x1 → v1,…, xn →vn} + ρ’
    • Eval(f e, ρ) => Eval(f (Eval(e, ρ)), ρ)
    • Eval(f (Val v), ρ) => Eval((Eval(f, ρ)) (Val v), ρ)
    • Eval((Val<(x1 , … , xn)→b, ρ’>)(Val(v1 , … , vn)), ρ) => Eval(b, {x1→v1 , … , xn→vn} + ρ’)

*

67

Evaluation

68 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval (plus_x z, ρ) =>

Eval (plus_x (Eval(z, ρ))) =>

Eval (plus_x (Val 3), ρ) =>

Eval ((Eval (plus_x, ρ)) (Val 3), ρ) =>

Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) => …

*

68

Your turn!

Evaluation

69 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval (plus_x z, ρ) =>

Eval (plus_x (Eval(z, ρ))) =>

Eval (plus_x (Val 3), ρ) =>

Eval ((Eval (plus_x, ρ)) (Val 3), ρ) =>

Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) => …

*

69

Keep going!

Evaluation

70 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval (plus_x z, ρ) =>

Eval (plus_x (Eval(z, ρ))) =>

Eval (plus_x (Val ?), ρ) =>

Eval ((Eval (plus_x, ρ)) (Val 3), ρ) =>

Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) => …

*

70

Look it up!

Evaluation

71 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval (plus_x z, ρ) =>

Eval (plus_x (Eval(z, ρ))) =>

Eval (plus_x (Val ?), ρ) =>

Eval ((Eval (plus_x, ρ)) (Val 3), ρ) =>

Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) => …

*

71

Look it up!

Evaluation

72 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval (plus_x z, ρ) =>

Eval (plus_x (Eval(z, ρ))) =>

Eval (plus_x (Val 3), ρ) =>

Eval ((Eval (plus_x, ρ)) (Val 3), ρ) =>

Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) => …

*

72

Done with argument!

Evaluation

73 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval (plus_x z, ρ) =>

Eval (plus_x (Eval(z, ρ))) =>

Eval (plus_x (Val 3), ρ) =>

Eval ((Eval (plus_x, ρ)) (Val 3), ρ) =>

Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) => …

*

73

Now what?

Evaluation

74 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval (plus_x z, ρ) =>

Eval (plus_x (Eval(z, ρ))) =>

Eval (plus_x (Val 3), ρ) =>

Eval ((Eval (plus_x, ρ)) (Val 3), ρ) =>

Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) => …

*

74

Now what?

Evaluation

75 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval (plus_x z, ρ) =>

Eval (plus_x (Eval(z, ρ))) =>

Eval (plus_x (Val 3), ρ) =>

Eval ((Eval (plus_x, ρ)) (Val 3), ρ) =>

Eval ((Val ?)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) => …

*

75

Look it up!

Evaluation

76 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval (plus_x z, ρ) =>

Eval (plus_x (Eval(z, ρ))) =>

Eval (plus_x (Val 3), ρ) =>

Eval ((Eval (plus_x, ρ)) (Val 3), ρ) =>

Eval ((Val ?)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) => …

*

76

Look it up!

Evaluation

77 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval (plus_x z, ρ) =>

Eval (plus_x (Eval(z, ρ))) =>

Eval (plus_x (Val 3), ρ) =>

Eval ((Eval (plus_x, ρ)) (Val 3), ρ) =>

Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) => …

*

77

Closure!

Evaluation

78 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval (plus_x z, ρ) =>

Eval (plus_x (Eval(z, ρ))) =>

Eval (plus_x (Val 3), ρ) =>

Eval ((Eval (plus_x, ρ)) (Val 3), ρ) =>

Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) => …

*

78

What’s next?

Evaluation

79 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) => …

*

79

How to evaluate closure?

Evaluation

80 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, … ) =>

*

80

Evaluate its body …

Evaluation

81 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, ? + ρplus_x ) =>

*

81

Evaluate its body in an updated environment!

Evaluation

82 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) =>

*

82

Evaluate its body in an updated environment!

Evaluation

83 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) =>

*

83

How to evaluate applied operator?

Evaluation

84 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) =>

Eval (y + Eval(x, {y → 3} + ρplus_x ), {y → 3} + ρplus_x ) =>

*

84

RHS first!

Evaluation

85 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) =>

Eval (y + Eval(x, {y → 3} + ρplus_x ), {y → 3} + ρplus_x ) =>

*

85

Look it up!

Evaluation

86 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) =>

Eval (y + Eval(x, {y → 3} + ρplus_x ), {y → 3} + ρplus_x ) =>

Eval (y + Val 12), {y → 3} + ρplus_x ) =>

*

86

Now what?

Evaluation

87 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) =>

Eval (y + Eval(x, {y → 3} + ρplus_x ), {y → 3} + ρplus_x ) =>

Eval (y + Val 12), {y → 3} + ρplus_x ) =>

*

87

LHS next!

Evaluation

88 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) =>

Eval (y + Eval(x, {y → 3} + ρplus_x ), {y → 3} + ρplus_x ) =>

Eval (y + Val 12), {y → 3} + ρplus_x ) =>

Eval (Eval(y, {y → 3} + ρplus_x ) + Val 12, {y → 3} + ρplus_x ) =>

*

88

LHS next!

Evaluation

89 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) =>

Eval (y + Eval(x, {y → 3} + ρplus_x ), {y → 3} + ρplus_x ) =>

Eval (y + Val 12), {y → 3} + ρplus_x ) =>

Eval (Eval(y, {y → 3} + ρplus_x ) + Val 12, {y → 3} + ρplus_x ) =>

*

89

Look it up in which environment?

Evaluation

90 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) =>

Eval (y + Eval(x, {y → 3} + ρplus_x ), {y → 3} + ρplus_x ) =>

Eval (y + Val 12), {y → 3} + ρplus_x ) =>

Eval (Eval(y, {y → 3} + ρplus_x ) + Val 12, {y → 3} + ρplus_x ) =>

*

90

Look it up locally!

Evaluation

91 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) =>

Eval (y + Eval(x, {y → 3} + ρplus_x ), {y → 3} + ρplus_x ) =>

Eval (y + Val 12), {y → 3} + ρplus_x ) =>

Eval (Eval(y, {y → 3} + ρplus_x ) + Val 12, {y → 3} + ρplus_x ) =>

Eval (Val 3 + Val 12 , {y → 3} + ρplus_x ) =>

*

91

Look it up locally!

Evaluation

92 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) =>

Eval (y + Eval(x, {y → 3} + ρplus_x ), {y → 3} + ρplus_x ) =>

Eval (y + Val 12), {y → 3} + ρplus_x ) =>

Eval (Eval(y, {y → 3} + ρplus_x ) + Val 12, {y → 3} + ρplus_x ) =>

Eval (Val 3 + Val 12, {y → 3} + ρplus_x ) =>

*

92

Finally, the operator!

Evaluation

93 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) =>

Eval (y + Eval(x, {y → 3} + ρplus_x ), {y → 3} + ρplus_x ) =>

Eval (y + Val 12), {y → 3} + ρplus_x ) =>

Eval (Eval(y, {y → 3} + ρplus_x ) + Val 12, {y → 3} + ρplus_x ) =>

Eval (Val 3 + Val 12, {y → 3} + ρplus_x ) =>

Val (3 + 12) = Val 15

*

93

Evaluation

94 of 116

Evaluation of Application of plus_x;;

  • Have environment:

ρ = { plus_x →<y → y + x, ρplus_x >, … ,

y → 19, x →17, z →3, … }

where: ρplus_x = {x → 12, … , y → 24, …}

  • Eval ((Val <y → y + x, ρplus_x >)(Val 3), ρ) =>

Eval (y + x, {y → 3} + ρplus_x ) =>

Eval (y + Eval(x, {y → 3} + ρplus_x ), {y → 3} + ρplus_x ) =>

Eval (y + Val 12), {y → 3} + ρplus_x ) =>

Eval (Eval(y, {y → 3} + ρplus_x ) + Val 12, {y → 3} + ρplus_x ) =>

Eval (Val 3 + Val 12, {y → 3} + ρplus_x ) =>

Val (3 + 12) = Val 15

*

94

Evaluation

95 of 116

95

Questions so far?

Evaluation

96 of 116

Evaluation of Application of plus_pair

  • Assume environment

ρ = {x → 3 , … , plus_pair →<(n, m) →n + m, ρplus_pair>}

+ ρplus_pair

  • Eval (plus_pair (4, x), ρ) =>

Eval (plus_pair (Eval ((4, x), ρ)), ρ) =>

Eval (plus_pair (Eval ((4, Eval (x , ρ)), ρ)), ρ) =>

Eval (plus_pair (Eval ((4, Val 3), ρ)), ρ) =>

Eval (plus_pair (Eval ((Eval (4, ρ), Val 3), ρ)), ρ) =>

Eval (plus_pair (Eval ((Val 4, Val 3), ρ)), ρ) =>

*

96

Evaluation

97 of 116

Evaluation of Application of plus_pair

  • Assume environment

ρ = {x → 3 , … , plus_pair →<(n, m) →n + m, ρplus_pair>}

+ ρplus_pair

  • Eval (plus_pair (4, x), ρ) =>

Eval (plus_pair (Eval ((4, x), ρ)), ρ) =>

Eval (plus_pair (Eval ((4, Eval (x , ρ)), ρ)), ρ) =>

Eval (plus_pair (Eval ((4, Val 3), ρ)), ρ) =>

Eval (plus_pair (Eval ((Eval (4, ρ), Val 3), ρ)), ρ) =>

Eval (plus_pair (Eval ((Val 4, Val 3), ρ)), ρ) =>

*

97

Evaluation

98 of 116

Evaluation of Application of plus_pair

  • Assume environment

ρ = {x → 3 , … , plus_pair →<(n, m) →n + m, ρplus_pair>}

+ ρplus_pair

  • Eval (plus_pair (4, x), ρ) =>

Eval (plus_pair (Eval ((4, x), ρ)), ρ) =>

Eval (plus_pair (Eval ((4, Eval (x , ρ)), ρ)), ρ) =>

Eval (plus_pair (Eval ((4, Val 3), ρ)), ρ) =>

Eval (plus_pair (Eval ((Eval (4, ρ), Val 3), ρ)), ρ) =>

Eval (plus_pair (Eval ((Val 4, Val 3), ρ)), ρ) =>

*

98

Evaluation

99 of 116

Evaluation of Application of plus_pair

  • Assume environment

ρ = {x → 3 , … , plus_pair →<(n, m) →n + m, ρplus_pair>}

+ ρplus_pair

  • Eval (plus_pair (4, x), ρ) =>

Eval (plus_pair (Eval ((4, x), ρ)), ρ) =>

Eval (plus_pair (Eval ((4, Eval (x , ρ)), ρ)), ρ) =>

Eval (plus_pair (Eval ((4, Val 3), ρ)), ρ) =>

Eval (plus_pair (Eval ((Eval (4, ρ), Val 3), ρ)), ρ) =>

Eval (plus_pair (Eval ((Val 4, Val 3), ρ)), ρ) =>

*

99

Evaluation

100 of 116

Evaluation of Application of plus_pair

  • Assume environment

ρ = {x → 3 , … , plus_pair →<(n, m) →n + m, ρplus_pair>}

+ ρplus_pair

  • Eval (plus_pair (4, x), ρ) =>

Eval (plus_pair (Eval ((4, x), ρ)), ρ) =>

Eval (plus_pair (Eval ((4, Eval (x , ρ)), ρ)), ρ) =>

Eval (plus_pair (Eval ((4, Val 3), ρ)), ρ) =>

Eval (plus_pair (Eval ((Eval (4, ρ), Val 3), ρ)), ρ) =>

Eval (plus_pair (Eval ((Val 4, Val 3), ρ)), ρ) =>

*

100

Evaluation

101 of 116

Evaluation of Application of plus_pair

  • Assume environment

ρ = {x → 3 , … , plus_pair →<(n, m) →n + m, ρplus_pair>}

+ ρplus_pair

  • Eval (plus_pair (4, x), ρ) =>

Eval (plus_pair (Eval ((4, x), ρ)), ρ) =>

Eval (plus_pair (Eval ((4, Eval (x , ρ)), ρ)), ρ) =>

Eval (plus_pair (Eval ((4, Val 3), ρ)), ρ) =>

Eval (plus_pair (Eval ((Eval (4, ρ), Val 3), ρ)), ρ) =>

Eval (plus_pair (Eval ((Val 4, Val 3), ρ)), ρ) =>

*

101

Evaluation

102 of 116

Evaluation of Application of plus_pair

  • Assume environment

ρ = {x → 3 , … , plus_pair →<(n, m) →n + m, ρplus_pair>}

+ ρplus_pair

  • Eval (plus_pair (4, x), ρ) =>

Eval (plus_pair (Eval ((4, x), ρ)), ρ) =>

Eval (plus_pair (Eval ((4, Eval (x , ρ)), ρ)), ρ) =>

Eval (plus_pair (Eval ((4, Val 3), ρ)), ρ) =>

Eval (plus_pair (Eval ((Eval (4, ρ), Val 3), ρ)), ρ) =>

Eval (plus_pair (Eval ((Val 4, Val 3), ρ)), ρ) =>

*

102

Evaluation

103 of 116

Evaluation of Application of plus_pair

  • Assume environment

ρ = {x → 3 , … , plus_pair →<(n, m) →n + m, ρplus_pair>}

+ ρplus_pair

  • Eval (plus_pair (4, x), ρ) =>

Eval (plus_pair (Eval ((4, x), ρ)), ρ) =>

Eval (plus_pair (Eval ((4, Eval (x , ρ)), ρ)), ρ) =>

Eval (plus_pair (Eval ((4, Val 3), ρ)), ρ) =>

Eval (plus_pair (Eval ((Eval (4, ρ), Val 3), ρ)), ρ) =>

Eval (plus_pair (Eval ((Val 4, Val 3), ρ)), ρ) =>

*

103

Evaluation

104 of 116

Evaluation of Application of plus_pair

  • Assume environment

ρ = {x → 3 , … , plus_pair →<(n, m) →n + m, ρplus_pair>}

+ ρplus_pair

  • Eval (plus_pair (Eval ((Val 4, Val 3), ρ)), ρ) =>

Eval (plus_pair (Val (4, 3)), ρ) =>

Eval (Eval (plus_pair, ρ), Val (4, 3)), ρ) => …

Eval ((Val<(n,m)→n+m, ρplus_pair>)(Val(4,3)) , ρ)=>

Eval (Val (n + m), {n -> 4, m -> 3} + ρplus_pair) =>

Eval (Val (4 + 3), {n -> 4, m -> 3} + ρplus_pair) =>

Val 7

*

104

Evaluation

105 of 116

Evaluation of Application of plus_pair

  • Assume environment

ρ = {x → 3 , … , plus_pair →<(n, m) →n + m, ρplus_pair>}

+ ρplus_pair

  • Eval (plus_pair (Eval ((Val 4, Val 3), ρ)), ρ) =>

Eval (plus_pair (Val (4, 3)), ρ) =>

Eval (Eval (plus_pair, ρ), Val (4, 3)), ρ) => …

Eval ((Val<(n,m)→n+m, ρplus_pair>)(Val(4,3)) , ρ)=>

Eval (Val (n + m), {n -> 4, m -> 3} + ρplus_pair) =>

Eval (Val (4 + 3), {n -> 4, m -> 3} + ρplus_pair) =>

Val 7

*

105

Evaluation

106 of 116

Evaluation of Application of plus_pair

  • Assume environment

ρ = {x → 3 , … , plus_pair →<(n, m) →n + m, ρplus_pair>}

+ ρplus_pair

  • Eval (plus_pair (Eval ((Val 4, Val 3), ρ)), ρ) =>

Eval (plus_pair (Val (4, 3)), ρ) =>

Eval (Eval (plus_pair, ρ), Val (4, 3)), ρ) => …

Eval ((Val<(n,m)→n+m, ρplus_pair>)(Val(4,3)) , ρ)=>

Eval (Val (n + m), {n -> 4, m -> 3} + ρplus_pair) =>

Eval (Val (4 + 3), {n -> 4, m -> 3} + ρplus_pair) =>

Val 7

*

106

Evaluation

107 of 116

Evaluation of Application of plus_pair

  • Assume environment

ρ = {x → 3 , … , plus_pair →<(n, m) →n + m, ρplus_pair>}

+ ρplus_pair

  • Eval (plus_pair (Eval ((Val 4, Val 3), ρ)), ρ) =>

Eval (plus_pair (Val (4, 3)), ρ) =>

Eval (Eval (plus_pair, ρ), Val (4, 3)), ρ) =>

Eval ((Val<(n,m)→n+m, ρplus_pair>)(Val(4,3)) , ρ)=>

Eval (Val (n + m), {n -> 4, m -> 3} + ρplus_pair) =>

Eval (Val (4 + 3), {n -> 4, m -> 3} + ρplus_pair) =>

Val 7

*

107

Evaluation

108 of 116

Evaluation of Application of plus_pair

  • Assume environment

ρ = {x → 3 , … , plus_pair →<(n, m) →n + m, ρplus_pair>}

+ ρplus_pair

  • Eval (plus_pair (Eval ((Val 4, Val 3), ρ)), ρ) =>

Eval (plus_pair (Val (4, 3)), ρ) =>

Eval (Eval (plus_pair, ρ), Val (4, 3)), ρ) =>

Eval ((Val<(n,m)→n+m, ρplus_pair>)(Val (4 , 3)) , ρ)=>

Eval (Val (n + m), {n -> 4, m -> 3} + ρplus_pair) =>

Eval (Val (4 + 3), {n -> 4, m -> 3} + ρplus_pair) =>

Val 7

*

108

Evaluation

109 of 116

Evaluation of Application of plus_pair

  • Assume environment

ρ = {x → 3 , … , plus_pair →<(n, m) →n + m, ρplus_pair>}

+ ρplus_pair

  • Eval (plus_pair (Eval ((Val 4, Val 3), ρ)), ρ) =>

Eval (plus_pair (Val (4, 3)), ρ) =>

Eval (Eval (plus_pair, ρ), Val (4, 3)), ρ) =>

Eval ((Val<(n,m)→n+m, ρplus_pair>)(Val (4 , 3)) , ρ)=>

Eval (Val (n + m), {n -> 4, m -> 3} + ρplus_pair) =>

Eval (Val (4 + 3), {n -> 4, m -> 3} + ρplus_pair) =>

Val 7

*

109

Evaluation

110 of 116

Evaluation of Application of plus_pair

  • Assume environment

ρ = {x → 3 , … , plus_pair →<(n, m) →n + m, ρplus_pair>}

+ ρplus_pair

  • Eval (plus_pair (Eval ((Val 4, Val 3), ρ)), ρ) =>

Eval (plus_pair (Val (4, 3)), ρ) =>

Eval (Eval (plus_pair, ρ), Val (4, 3)), ρ) =>

Eval ((Val<(n,m)→n+m, ρplus_pair>)(Val (4 , 3)) , ρ)=>

Eval (Val (n + m), {n -> 4, m -> 3} + ρplus_pair) =>

Eval (Val (4 + 3), {n -> 4, m -> 3} + ρplus_pair) =>

Val 7

*

110

Evaluation

111 of 116

Evaluation of Application of plus_pair

  • Assume environment

ρ = {x → 3 , … , plus_pair →<(n, m) →n + m, ρplus_pair>}

+ ρplus_pair

  • Eval (plus_pair (Eval ((Val 4, Val 3), ρ)), ρ) =>

Eval (plus_pair (Val (4, 3)), ρ) =>

Eval (Eval (plus_pair, ρ), Val (4, 3)), ρ) =>

Eval ((Val<(n,m)→n+m, ρplus_pair>)(Val (4 , 3)) , ρ)=>

Eval (Val (n + m), {n -> 4, m -> 3} + ρplus_pair) =>

Eval (Val (4 + 3), {n -> 4, m -> 3} + ρplus_pair) =>

Val 7

*

111

Evaluation

112 of 116

Evaluation of Application of plus_pair

  • Assume environment

ρ = {x → 3 , … , plus_pair →<(n, m) →n + m, ρplus_pair>}

+ ρplus_pair

  • Eval (plus_pair (Eval ((Val 4, Val 3), ρ)), ρ) =>

Eval (plus_pair (Val (4, 3)), ρ) =>

Eval (Eval (plus_pair, ρ), Val (4, 3)), ρ) =>

Eval ((Val<(n,m)→n+m, ρplus_pair>)(Val (4 , 3)) , ρ)=>

Eval (Val (n + m), {n -> 4, m -> 3} + ρplus_pair) =>

Eval (Val (4 + 3), {n -> 4, m -> 3} + ρplus_pair) =>

Val 7

*

112

Evaluation

113 of 116

113

Questions?

114 of 116

  • To use recursion in OCaml, you need the rec keyword
  • Evaluation takes expression e and an environment ρ, and evaluates e in ρ to some value v:
    • Eval (e , ρ) => v
  • We define evaluation one small step at a time. So when evaluating an expression e requires recursively evaluating, we write:
    • Eval (e , ρ) => Eval (e’ , ρ’)

for subexpression e’ and updated environment ρ’

  • This gives an algorithm for an interpreter!

Takeaways

114

115 of 116

115

Next Class:

Lists, more recursion

116 of 116

  • MP2 due Tuesday
    • This is worth points!
    • Please do this!
    • WA2 due next Thursday
    • All deadlines can be found on course website
    • Use office hours and class forums for help

Reminder: Also Next Class

116

Next Class