Jeremy Siek 3 年之前
父節點
當前提交
9428915723
共有 1 個文件被更改,包括 32 次插入31 次删除
  1. 32 31
      book.tex

+ 32 - 31
book.tex

@@ -1816,11 +1816,10 @@ book we define many interpreters, one for each of the languages that
 we study. Because each language builds on the prior one, there is a
 we study. Because each language builds on the prior one, there is a
 lot of commonality between these interpreters. We want to write down
 lot of commonality between these interpreters. We want to write down
 the common parts just once instead of many times. A naive approach
 the common parts just once instead of many times. A naive approach
-would be to have, for example, the interpreter for \LangVar{} handle
-the cases for variables and \code{let} and then have a default case
-that dispatches to the interpreter for \LangInt{}. The following code
-sketches this idea. (We explain the \code{env} parameter soon, in
-Section~\ref{sec:interp-Lvar}.)
+would be for the interpreter of \LangVar{} to handle the cases for
+variables and \code{let} but dispatch to \LangInt{} for the rest of
+the cases. The following code sketches this idea. (We explain the
+\code{env} parameter soon, in Section~\ref{sec:interp-Lvar}.)
 
 
 \begin{center}
 \begin{center}
 {\if\edition\racketEd  
 {\if\edition\racketEd  
@@ -1878,7 +1877,9 @@ def interp_Lvar(e):
 The problem with this approach is that it does not handle situations
 The problem with this approach is that it does not handle situations
 in which an \LangVar{} feature, such as a variable, is nested inside
 in which an \LangVar{} feature, such as a variable, is nested inside
 an \LangInt{} feature, like the \code{-} operator, as in the following
 an \LangInt{} feature, like the \code{-} operator, as in the following
-program.  {\if\edition\racketEd
+program.
+%
+{\if\edition\racketEd
 \begin{lstlisting}
 \begin{lstlisting}
 (Let 'y (Int 10) (Prim '- (list (Var 'y))))
 (Let 'y (Int 10) (Prim '- (list (Var 'y))))
 \end{lstlisting}
 \end{lstlisting}
@@ -1890,19 +1891,19 @@ print(-y)
 \end{lstlisting}
 \end{lstlisting}
 \fi}
 \fi}
 %
 %
-If we invoke \code{interp\_Lvar} on this program, it dispatches to
-\code{interp\_Lint} to handle the \code{-} operator, but then it
-recursively calls \code{interp\_Lint} again on the argument of
-\code{-}, which is a \code{Var}.  But there is no case for \code{Var}
-in \code{interp\_Lint} so we get an error!
+\noindent If we invoke \code{interp\_Lvar} on this program, it
+dispatches to \code{interp\_Lint} to handle the \code{-} operator, but
+then it recursively calls \code{interp\_Lint} again on its argument.
+But there is no case for \code{Var} in \code{interp\_Lint} so we get
+an error!
 
 
 To make our interpreters extensible we need something called
 To make our interpreters extensible we need something called
 \emph{open recursion}\index{subject}{open recursion}, where the tying of the
 \emph{open recursion}\index{subject}{open recursion}, where the tying of the
 recursive knot is delayed to when the functions are
 recursive knot is delayed to when the functions are
 composed. Object-oriented languages provide open recursion via
 composed. Object-oriented languages provide open recursion via
 method overriding\index{subject}{method overriding}. The
 method overriding\index{subject}{method overriding}. The
-following code uses method overriding to interpret \LangVar{} and
-\LangIf{} using
+following code uses method overriding to interpret \LangInt{} and
+\LangVar{} using
 %
 %
 \racket{the
 \racket{the
   \href{https://docs.racket-lang.org/guide/classes.html}{\code{class}}
   \href{https://docs.racket-lang.org/guide/classes.html}{\code{class}}
@@ -1911,13 +1912,13 @@ following code uses method overriding to interpret \LangVar{} and
 \python{a Python \code{class} definition}.
 \python{a Python \code{class} definition}.
 %
 %
 We define one class for each language and define a method for
 We define one class for each language and define a method for
-interpreting expressions inside each class. The class for \LangIf{}
-inherits from the class for \LangVar{} and the method
-\code{interp\_exp} in \LangIf{} overrides the \code{interp\_exp} in
-\LangVar{}. Note that the default case of \code{interp\_exp} in
-\LangIf{} uses \code{super} to invoke \code{interp\_exp}, and because
-\LangIf{} inherits from \LangVar{}, that dispatches to the
-\code{interp\_exp} in \LangVar{}.
+interpreting expressions inside each class. The class for \LangVar{}
+inherits from the class for \LangInt{} and the method
+\code{interp\_exp} in \LangVar{} overrides the \code{interp\_exp} in
+\LangInt{}. Note that the default case of \code{interp\_exp} in
+\LangVar{} uses \code{super} to invoke \code{interp\_exp}, and because
+\LangVar{} inherits from \LangInt{}, that dispatches to the
+\code{interp\_exp} in \LangInt{}.
 \begin{center}
 \begin{center}
 {\if\edition\racketEd  
 {\if\edition\racketEd  
 \begin{minipage}{0.45\textwidth}
 \begin{minipage}{0.45\textwidth}
@@ -1953,7 +1954,7 @@ inherits from the class for \LangVar{} and the method
 {\if\edition\pythonEd
 {\if\edition\pythonEd
 \begin{minipage}{0.45\textwidth}
 \begin{minipage}{0.45\textwidth}
 \begin{lstlisting}
 \begin{lstlisting}
-class InterpLvar:
+class InterpLint:
   def interp_exp(e):
   def interp_exp(e):
      match e:
      match e:
        case UnaryOp(USub(), e1):
        case UnaryOp(USub(), e1):
@@ -1964,7 +1965,7 @@ class InterpLvar:
 \end{minipage}
 \end{minipage}
 \begin{minipage}{0.45\textwidth}
 \begin{minipage}{0.45\textwidth}
   \begin{lstlisting}
   \begin{lstlisting}
-def InterpLif(InterpRVar):
+def InterpLvar(InterpRVar):
   def interp_exp(e):
   def interp_exp(e):
     match e:
     match e:
       case IfExp(cnd, thn, els):
       case IfExp(cnd, thn, els):
@@ -1993,8 +1994,8 @@ y = 10
 print(-y)
 print(-y)
 \end{lstlisting}
 \end{lstlisting}
 \fi}
 \fi}
-\noindent We can invoke the \code{interp\_exp} method for \LangIf{} on this
-expression, call it \code{e0}, by creating an object of the \LangIf{} class
+\noindent We can invoke the \code{interp\_exp} method for \LangVar{} on this
+expression, call it \code{e0}, by creating an object of the \LangVar{} class
 and calling the \code{interp\_exp} method.
 and calling the \code{interp\_exp} method.
 {\if\edition\racketEd
 {\if\edition\racketEd
 \begin{lstlisting}
 \begin{lstlisting}
@@ -2003,15 +2004,15 @@ and calling the \code{interp\_exp} method.
 \fi}
 \fi}
 {\if\edition\pythonEd
 {\if\edition\pythonEd
 \begin{lstlisting}
 \begin{lstlisting}
-InterpLif().interp_exp(e0)
+InterpLvar().interp_exp(e0)
 \end{lstlisting}
 \end{lstlisting}
 \fi}
 \fi}
-\noindent The default case of \code{interp\_exp} in \LangVar{} handles it by
-dispatching to the \code{interp\_exp} method in \LangInt{}, which
-handles the \code{-} operator. But then for the recursive method call,
-it dispatches back to \code{interp\_exp} in \LangVar{}, where the
-\code{Var} node is handled correctly. Thus, method overriding gives us the
-open recursion that we need to implement our interpreters in an
+\noindent To process the \code{-} operator, the default case of
+\code{interp\_exp} in \LangVar{} dispatches to the \code{interp\_exp}
+method in \LangInt{}. But then for the recursive method call, it
+dispatches back to \code{interp\_exp} in \LangVar{}, where the
+\code{Var} node is handled correctly. Thus, method overriding gives us
+the open recursion that we need to implement our interpreters in an
 extensible way.
 extensible way.