Closures

Past three weeks

How to use essential language constructs?

  • Data Types
  • Recursion
  • Higher-Order Functions

Next two weeks

How to implement language constructs?

  • Local variables and scope
  • Environments and Closures

Interpreter

How do we represent and evaluate a program?










How should we evaluate this expression?


What is the value of cTimes???










Rethinking our values

Until now: a program evaluates to an integer (or fails)



What do these programs evaluate to?







Now: a program evaluates to an integer or a lambda abstraction (or fails)

  • Remember: functions are first-class values


Let’s change our definition of values!










Function values

How should we represent a function value?

We need to store enough information about cTimes so that we can later evaluate any application of cTimes (like cTimes 2)!



First attempt:



Let’s try this!


Looks good… can you spot a problem?










QUIZ

What should this evaluate to?

(A) 84

(B) 10

(C) Error: multiple definitions of c










Static vs Dynamic Scoping

What we want:

Lexical (or static) scoping:

  • each occurrence of a variable refers to the most recent binding in the program text
  • definition of each variable is unique and known statically
  • good for readability and debugging: don’t have to figure out where a variable got “assigned”



What we don’t want:

Dynamic scoping:

  • each occurrence of a variable refers to the most recent binding during program execution
  • can’t tell where a variable is defined just by looking at the function body
  • nightmare for readability and debugging:










Function values

This representation can only implement dynamic scoping!

evaluates as:

Lesson learned: need to remember what c was bound to when cTimes was defined!

  • i.e. “freeze” the environment at function definition










Closures

To implement lexical scoping, we will represent function values as closures


Closure = lambda abstraction (formal + body) + environment at function definition



Our example:










QUIZ

Which variables should be saved in the closure environment of f?

(A) a

(B) a x

(C) y g

(D) a y g

(E) a x y g z










Free vs bound variables

  • An occurrence of x is free if it is not bound
  • An occurrence of x is bound if it’s inside
    • e2 where let x = e1 in e2
    • e where \x -> e
  • A closure environment has to save all free variables of a function definition!










Evaluator

Let’s modify our evaluator to handle functions!










Evaluating functions:

  • Construct a closure: save environment at function definition
  • Apply a closure: restore saved environment, add formal, evaluate the body

QUIZ

With eval as defined above, what does this evaluate to?

(A) 15

(B) 5

(C) Error: unbound variable x

(D) Error: unbound variable y

(E) Error: unbound variable f

















QUIZ

With eval as defined above, what does this evaluate to?

(A) 120

(B) Evaluation does not terminate

(C) Error: unbound variable f









Lesson learned: to support recursion, we need a different way of constructing the closure environment!










The Nano Language

Features of Nano:

  1. Arithmetic expressions [done]
  2. Variables and let-bindings [done]
  3. Functions [done]
  4. Recursion [this is part of HW4]