 % -*- Mode: Tex -*-

%\input /home/welg/6001mac.tex
%\input /homes/welg/6001/6001mac.tex
%\input /zu/scheme/6001ARCHIVE/fall89/6001mac.tex
\input ./6001mac.tex

{\obeyspaces\gdef {\ }}


\def\fbox#1{%
  \vtop{\vbox{\hrule%
              \hbox{\vrule\kern3pt%
                    \vtop{\vbox{\kern3pt#1}\kern3pt}%
                    \kern3pt\vrule}}%
        \hrule}}

\def\emptybox#1#2{\fbox{\vbox to #2{\hbox to #1 {\null}}}}

\def\pscenter#1{\hbox to\hsize{\hss\psadobenomag{#1}\hss}}

\setlength{\textheight}{9.2in}

\begin{document}

\psetheader{Spring Semester, 1998}{Recitation -- Wednesday, April 22}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

{\Large\bf 1. Student Presentations}

{\bf Presentation 1:} Discuss section 4.2.1, on normal order
evaluation vs applicative order evaluation. Do exercise 4.25.

{\bf Presentation 2:} Explain why the following expression does not
work: 

\beginlisp
(let ((fact (lambda (n) 
              (if (= n 1)
                  1
                  (* n (fact (- n 1)))))))
  (fact 5))
\endlisp

There is a special form {\tt let-rec} that allows for these types of
recursive definitions.  Show how to desugar {\tt let-rec} into a call
to {\tt let} using some {set!}'s and explain why it works.  

\vskip .08in

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

{\Large\bf 2.  Playing with Scope}

Let's take a look at our old friend {\tt make-acct}:

\beginlisp
(define make-acct 
  (lambda (balance)
    (lambda (msg . args)
      (case msg 
        ((BALANCE) balance)
        ((DEPOSIT) (set! balance (+ balance (cadr args))))))))
\null
(define a (make-acct 100))
(a 'balance)            ==> 100
\null
(define b
  (let ((balance 1000))
    a))
(b 'balance)            ==> 100
\endlisp

Why does {\tt b} have a balance of 100 and not 1000?  Let's quickly
sketch the environment diagram for the above expressions.

% Dynamic vs. Static Scoping.

\newpage
{\Large\bf 3. Re-scoping a procedure}

Consider a new special form called {\tt rescope} that takes a
procedure and returns a procedure with the same parameters and body,
but whose environment pointer points to the current environment.
Consider defining another account {\tt c} by rescoping {\tt a}
(instead of by calling {\tt make-acct}).

\beginlisp
(define c
  (let ((balance 1000))
    (rescope a)))
\null
(c 'balance)            ==> 1000
\endlisp

Let's add the special form {\tt rescope} to the mc-evalutator.

{\bf (1) Define Data Abstraction}

\beginlisp
 (define (rescope? exp)                             ) 
% (tagged-list? exp 'rescope))
 (define (rescope-exp exp)                          ) 
% (cadr exp))
\endlisp

{\bf (2) Add the appropriate {\tt cond} clause to {\tt mc-eval}}

\beginlisp
%         ((rescope? exp) (eval-rescope exp env))
\null
\endlisp

{\bf (3) Write {\tt eval-rescope}}

\beginlisp
(define (eval-rescope exp env)
%   (let ((proc (mc-eval (rescope-exp exp) env)))
%     (if (compound-procedure? proc)
%         (make-procedure (procedure-parameters proc)
%                         (procedure-body proc)
%                         env)
%         (error "Bad argument to rescope")))
\null
\null
\null
\null
\null
)
\endlisp

\vskip 0.1in

{\Large\bf 4. Grabbing procedure's scope}

Consider a new special form called {\tt inscope} that takes a
procedure and an expression and then evaluates the expression with
respect to the procedure's environment. 
For example

\beginlisp
(define d
  (inscope a (lambda () (set! balance 'loser))))
\null
(a 'balance)            ==> 100
(d)
(a 'balance)            ==> loser
\endlisp

Let's add the special form {\tt inscope} to the mc-evalutator.

{\bf (1) Define Data Abstraction}

\beginlisp
(define (inscope? exp)                              ) 
% (tagged-list? exp 'inscope))
(define (inscope-procedure exp)                     ) 
% (cadr exp))
(define (inscope-body exp)                          ) 
% (caddr exp))
\endlisp

{\bf (2) Add the appropriate {\tt cond} clause to {\tt mc-eval}}

\beginlisp
%        ((inscope? exp) (eval-inscope exp env))
\null
\endlisp

{\bf (3) Write {\tt eval-inscope}}

\beginlisp
(define (eval-inscope exp env)
%   (let ((proc (mc-eval (rescope-exp exp) env)))
%     (if (compound-procedure? proc)
%         (mc-eval (inscope-body exp)       
%               (procedure-environment proc))
%         (error "Bad procedure to inscope")))
\null
\null
\null
\null
\null
)
\endlisp

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\end{document}


{\Large\bf 5. Discussion}

Why doesn't Scheme have these special forms?  They provide a lot more
flexibility 


For example

\beginlisp
(define foo
  (let ((x 1))
    (lambda (y) (+ x y))))
\null
(foo 2)                                 ==> 3
\null
(let ((x 10)) ((rescope foo) 2))        ==> 12
\endlisp

