recitation 20: metacircular evaluator

=========================================================================
eval/apply:

eval needs exp & env
apply needs proc & args

concrete representation for environment, list of frames

=========================================================================
lexical scoping (static scoping): look up free variables in
  procedure's surrounding lexical environment -- REGULAR SCHEME

dynamic scoping: look up free variables in caller's environment, 
  don't need env pointer any more!!

(define a 1)
(define (b) a)
(define (c a) (lambda (a) (b)))
(define d (c 2))
(d 3)

* draw environment diagram to execute with lexical scoping
* draw environment diagram to execute with dynamic scoping
=========================================================================

semantics: what the language *means*, model of computation
syntax: particulars of *writing* expressions
    abstracted by the detectors & accessors
  
building our own evaluator allows us to modify the syntax and/or
semantics of the language

semantic implementation vs. syntactic transformation (desugar it)

* write a syntactic translator for let*

* write a semantic implementation for let*

=========================================================================
(ex 4.8 from book)

* write a syntactic translator for named-let

(let <var> <bindings> <body>)

The <bindings> and <body> are just as in ordinary let, except that
<var> is bound within <body> to a procedure whose body is <body> and
whose parameters are the variables in the <bindings>. Thus, one can
repeatedly execute the <body> by invoking the procedure named
<var>. For example, the iterative Fibonacci procedure 
can be rewritten using named let as follows:

(define (fib n)
  (let fib-iter ((a 1)
                 (b 0)
                 (count n))
    (if (= count 0)
        b
        (fib-iter (+ a b) a (- count 1)))))

=========================================================================