Closures - PowerPoint PPT Presentation

1 / 26
About This Presentation
Title:

Closures

Description:

... other functions (map), return from functions (compose), place in data structures. ... val compose = fn (f,g) = (fn x = f(g(x))) val id = compose(inc,dec) ... – PowerPoint PPT presentation

Number of Views:112
Avg rating:3.0/5.0
Slides: 27
Provided by: gregmor
Category:
Tags: closures | compose

less

Transcript and Presenter's Notes

Title: Closures


1
Closures Environments
  • CS153 Compilers
  • Greg Morrisett

2
"Functional" Languages
  • Lisp, Scheme, Miranda, Hope, ML, OCaml, Haskell,
  • Functions are first-class
  • not just for calling
  • can pass to other functions (map), return from
    functions (compose), place in data structures.
  • Functions nest
  • A nested function can refer to variables bound in
    an outer function.

3
Nesting
  • let add fun x -gt (fun y -gt yx)
  • let inc add 1 ( fun y -gt y 1 )
  • let dec add 1 ( fun y -gt y - 1 )
  • let compose fun f -gt fun g -gt fun x -gt f(g x)
  • let id compose inc dec
  • ( fun x -gt inc(dec x) )
  • ( fun x -gt (fun y -gt y1)((fun y -gt y-1) x)
    )
  • ( fun x -gt (fun y -gt y1)(x-1)) )
  • ( fun x -gt (x-1)1 )
  • After calling add, we can't just throw away its
    arguments (or local variables) because those
    values are needed in the nested function that it
    returns.

4
Substitution-Based Semantics
  • type exp Int of int Plus of expexp Var of
    var Lambda of varexp App of expexp
  • let rec eval (eexp)
  • match e with
  • Int i -gt Int i
  • Plus(e1,e2) -gt
  • (match eval e1,eval e2 with
  • Int i,Int j -gt Int(ij))
  • Var x -gt error ("Unbound variable "x)
  • Lambda(x,e) -gt Lambda(x,e)
  • App(e1,e2) -gt
  • (match eval e1, eval e2 with
  • (Lambda(x,e),v) -gt
  • eval (substitute v x e)))

5
Substitution-Based Semantics
  • let rec subst (vexp) (xvar) (eexp)
  • match e with
  • Int i -gt Int i
  • Plus(e1,e2) -gt Plus(subst v x e1,subst v x
    e2)
  • Var y -gt if y x then v else Var y
  • Lambda(y,e) -gt
  • if y x then Lambda(x,e) else
    Lambda(x,subst v x e)
  • App(e1,e2) -gt App(subst v x e1,subst v x e2)

6
Example
  • App(App(Lambda(x,Lambda(y,Plus(Var x,Var y)),Int
    3),Int 4)
  • App(Lambda(x,Lambda(y,Plus(Var x,Var y)),Int 3)
  • Lambda(x,Lambda(y,Plus(Var x,Var y))
  • Int 3
  • eval(subst(Int 3) x )Lambda(y,Plus(Var x,Var
    y))))
  • Lambda(y,Plus(Int 3,Var y))
  • Lambda(y,Plus(Int 3,Var y))
  • Int 4
  • subst(Int 4) y (Plus(Int 3,Var y))
  • Plus(Int 3,Int 4)
  • Int 3
  • Int 4
  • Int 7

7
Problems
  • Eval crawls over an expression.
  • Substitute crawls over an expression.
  • So eval (substitute v x e)) is pretty stupid.
    Why not evaluate as we substitute?

8
First Attempt
  • type env (exp value) list
  • let rec eval (eexp) (envenv) value
  • match e with
  • Int i -gt Int i
  • Var x -gt lookup env x
  • Lambda(x,e) -gt Lambda(x,e)
  • App(e1,e2) -gt
  • (match eval e1 env, eval e2 env with
  • Lambda(x,e), v -gt
  • eval e ((x,v)env))

9
Second Attempt
  • type env (exp value) list
  • let rec eval (eexp) (envenv) value
  • match e with
  • Int i -gt Int i
  • Var x -gt lookup env x
  • Lambda(x,e) -gt Lambda(x,subst env e)
  • App(e1,e2) -gt
  • (match eval e1 env, eval e2 env with
  • Lambda(x,e), v -gt
  • eval e ((x,v)env))

10
Aha!
  • Instead of doing the substitution when we reach a
    lambda, we could instead make a promise to finish
    the substitution if the lambda is ever applied.
  • Lambda(x,subst env e) as code gt
    Promise(subst,code)
  • Then we have to modify App(_,_) to take care of
    the delayed substitution

11
Closure-Based Semantics
  • type value Int_v of int
  • Closure_v of envenv, bodyvarexp
  • and env (var value) list
  • let rec eval (eexp) (envenv) value
  • match e with
  • Int i -gt Int_v i
  • Var x -gt lookup env x
  • Lambda(x,e) -gt Closure_venvenv,body(x,e)
  • App(e1,e2) gt
  • (match eval e1 env, eval e2 env with
  • Closure_venvcenv,body(x,e), v -gt
  • eval e ((x,v)cenv))

12
Speeding up the Interpreter
  • We have to do expensive string comparisons when
    looking up a variable
  • Var x gt lookup env x
  • where
  • let rec lookup env x
  • match env with
  • ((y,v)rest) -gt
  • if y x then v else lookup rest
    -gt error unbound variable

13
DeBruijn Indices
  • Instead of using strings to represent variables,
    let's use natural numbers
  • type exp Int of int Var of int Lambda of
    exp App of expexp
  • The numbers will represent lexical depth
  • fun x -gt fun y -gt fun z -gt xyz
  • fun x2 -gt fun x1 -gt fun x0 -gt x2x1x0
  • fun -gt fun -gt fun -gt 210

14
Graphs as Trees
  • fun x -gt fun y -gt fun z -gt x(yz)

fn x
fn y
fn z

x

z
y
15
Graphs as Trees
  • fun -gt fun -gt fun -gt 2 (1 0)

fn
fn
fn

2

0
1
16
Converting
  • let rec cvt (eexp) (envvar-gtint) D.exp
  • match e with
  • Int i -gt D.Int i
  • Var x -gt D.Var (env x)
  • App(e1,e2) -gt
  • D.App(cvt e1 env,cvt e2 env)
  • Lambda(x,e) gt
  • let new_env(y)
  • if y x then 0 else (env y)1
  • in
  • Lambda(cvt e env)

17
New Interpreter
  • type value Int_v of int
  • Closure_v of envenv, bodyexp
  • and env value list
  • let rec eval (eexp) (envenv) value
  • match e with
  • Int i -gt Int_v i
  • Var n -gt List.nth(env,n)
  • Lambda e -gt Closure_venvenv,bodye
  • App(e1,e2) -gt
  • (match eval e1 env, eval e2 env with
  • Closure_venvcenv,bodye, v -gt
  • eval e (vcenv))

18
Environments
  • (((fun -gt fun -gt fun -gt 2 (1 0))
    42) 37) 21

fn
fn
fn

2

0
1
19
Environments
  • (((fun -gt fun -gt fun -gt 2 (1 0))
    42) 37) 21

fn
fn
fn

42
2

env
0
1
20
Environments
  • (((fun -gt fun -gt fun -gt 2 (1 0))
    42) 37) 21

fn
fn
fn

42
2

37
0
1
env
21
Environments
  • (((fun -gt fun -gt fun -gt 2 (1 0))
    42) 37) 21

fn
fn
fn

42
2

37
0
1
21
env
22
Alternative
  • type value Int_v of int
  • Closure_v of envenv, bodyexp
  • and env value vector
  • let rec eval (eexp) (envenv) value
  • match e with
  • Int i -gt Int_v i
  • Var n -gt Vector.sub(env,n)
  • Lambda(e) -gt Closure_venvenv,bodye
  • App(e1,e2) -gt
  • (match eval e1 env, eval e2 env with
  • Closure_venvcenv,bodye, v -gt
  • eval e (vector_cons(v,cenv)))

23
Flat Environments
  • (((fun -gt fun -gt fun -gt 2 (1 0))
    42) 37) 21

fn
fn
fn

42
2

env
0
1
24
Flat Environments
  • (((fun -gt fun -gt fun -gt 2 (1 0))
    42) 37) 21

fn
fn
fn

42
2

37 42
0
1
env
25
Flat Environments
  • (((fun -gt fun -gt fun -gt 2 (1 0))
    42) 37) 21

fn
fn
fn

42
2

37 42
0
1
21 37 42
env
26
Schemeish Environments
  • (lambda (x y z) (lambda (n m) (lambda (p) ( n
    z))

x,y,z
n,m
p
fn 3
fn 2
fn 1
x y z nil

1,0
2,2
n m nxt
p nxt
Write a Comment
User Comments (0)
About PowerShow.com