\input 6001mac
%\input psfig
\addtolength{\textheight}{1cm}
%\addtolength{\topmargin}{-1cm}

\newcommand{\comment}[1]{}

\renewenvironment{lisp}{%
  \par
  \begin{minipage}[t]{\linewidth}
  \begin{list}{$\bullet$}{%
    \setlength{\topsep}{0in}
    \setlength{\partopsep}{0in}
    \setlength{\itemsep}{0in}
    \setlength{\parsep}{0in}
    \setlength{\leftmargin}{1.5em}
    \setlength{\rightmargin}{0in}
    \setlength{\itemindent}{0in}
  }\item[]
  \obeyspaces
  \obeylines \small\tt}{%
  \end{list}
  \end{minipage}
  \par
  }



\begin{document}

\psetheader{Fall Semester, 1996}
{Lecture Notes, October 22 -- State and Mutation}

\subsubsection{Environment Model}
\begin{enumerate}
  \item To evaluate a combination: evaluate subexpressions then 
apply value of operator subexpression to values of operand 
subexpressions.

  \item Value of a variable w.r.t. an environment is the value given
by the binding of the variable in the first frame in the environment
that contains such a binding.

  \item A lambda expression produces a procedure object:
    \begin{itemize}
      \item {\bf code} (parameters and body) are given by the text of the 
lambda and are stored away for later use
      \item {\bf environment pointer} points to the environment in which 
the lambda expression was evaluated
    \end{itemize}

  \item Define adds a binding to the current frame

  \item To apply a procedure object to a set of arguments:
    \begin{itemize}
\item Create a new frame
\item Hang the frame from the environment part of the procedure 
object being applied
\item In the new frame, bind the formal parameters of the 
procedure to the actual arguments
\item Evaluate the body of the procedure in the context of the new 
environment
    \end{itemize}

\item To evaluate {\tt (set! <var> <exp>)} w.r.t. an environment E:
  \begin{itemize}
    \item Evaluate {\tt <exp>} w.r.t. E
    \item Find and change the nearest binding for {\tt <var>} in E to
hold value of {\tt <exp>}
  \end{itemize}
\end{enumerate}


\subsubsection{Implications of Mutation}
\framebox[6.5in]{\rule{0in}{2in}}

\comment{

\subsubsection{Misuse of Set!}

\begin{lisp}
{\it ;; Functional programming style}
(define (factorial n)
  (define (iter product counter)
    (if (> counter n)
        product
        (iter (* counter product)
              (+ counter 1))))
  (iter 1 1))
\null
\null
{\it ;; Imperative programming style -- DEPRECATED}
(define (factorial n)
  (let ((product 1)
        (counter 1))
    (define (iter)
      (if (> counter n)
          product
          (begin (set! product (* counter product))
                 (set! counter (+ counter 1))
                 (iter))))
    (iter)))
\end{lisp}

}


\subsubsection{Message-Passing Ship Implementation}
\begin{lisp}
(define (make-ship x-pos y-pos time-left)
  (define (move dx dy)
    (set! x-pos (+ x-pos dx))
    (set! y-pos (+ y-pos dy))
    (list x-pos y-pos))
  (define (count-down)
    (set! time-left (- time-left 1))
    (if (<= time-left 0)
        'blast-off
        time-left))
  (define (dispatch message)
    (cond ((eq? message 'move) move)
          ((eq? message 'count-down) count-down)
          (else (error "No method" message))))
  dispatch)
\null
(define enterprise (make-spaceship 0 0 10))
\null
((enterprise 'move) 1 2) ==> (1 2)
\end{lisp}

\subsubsection{Data-Directed Ship Implementation}
\begin{lisp}
(define (install-ship-package)
  ;; Internal representation
  (define (make-ship x y time) (list x y time))
  ; Accessors
  (define (ship-x ship) (car ship))
  (define (ship-y ship) (cadr ship))
  ; Mutators
  (define (set-ship-x! ship new-x)
    (set-car! ship new-x))
  (define (set-ship-y! ship new-y)
    (set-car! (cdr ship) new-y))
  ; Operations
  (define (move ship dx dy)
    (set-ship-x! (+ (ship-x ship) dx))
    (set-ship-y! (+ (ship-y ship) dy))
    (list (ship-x ship) (ship-y ship)))
\null
  ;; External representation - tagged object
  (define (tag x) (attach-tag 'spaceship x))
  (put 'make 'spaceship
    (lambda (x y t) (tag (make-ship x y t))))
  (put 'move 'spaceship 
    (lambda (s dx dy) (tag (move s dx dy))))
  'done
  )
\null
(define (move obj dx dy)
  (apply-generic 'move obj dx dy)
\end{lisp}

\end{document}
