Jeremy Siek 3 years ago
parent
commit
c1ed888ac3
2 changed files with 427 additions and 103 deletions
  1. 421 101
      book.tex
  2. 6 2
      defs.tex

+ 421 - 101
book.tex

@@ -12716,39 +12716,83 @@ mark. The following example uses \code{set-point-x!} to change the
 % TODO: create an interpreter for L_struct
 
 \clearpage
+\fi}
 
 \section{Challenge: Arrays}
 \label{sec:arrays}
 
-In Chapter~\ref{ch:Lvec} we studied tuples, that is, a heterogeneous
+In this chapter we have studied tuples, that is, a heterogeneous
 sequences of elements whose length is determined at compile-time. This
 challenge is also about sequences, but this time the length is
 determined at run-time and all the elements have the same type (they
 are homogeneous). We use the term ``array'' for this later kind of
 sequence.
-
+%
+\racket{
 The Racket language does not distinguish between tuples and arrays,
 they are both represented by vectors. However, Typed Racket
 distinguishes between tuples and arrays: the \code{Vector} type is for
-tuples and the \code{Vectorof} type is for arrays.
-%
+tuples and the \code{Vectorof} type is for arrays.}
+\python{
+Arrays correspond to the \code{list} type in Python language.
+}
+
 Figure~\ref{fig:Lvecof-concrete-syntax} defines the concrete syntax
-for \LangArray{}, extending \LangLoop{} with the \code{Vectorof} type
-and the \code{make-vector} primitive operator for creating an array,
+for \LangArray{} and Figure~\ref{fig:Lvecof-syntax} defines the
+abstract syntax, extending \LangVec{} with the
+\racket{\code{Vectorof}}\python{\code{list}} type and the
+%
+\racket{\code{make-vector} primitive operator for creating an array,
 whose arguments are the length of the array and an initial value for
-all the elements in the array. The \code{vector-length},
+all the elements in the array.}
+\python{bracket notation for creating an array literal.}
+\racket{
+The \code{vector-length},
 \code{vector-ref}, and \code{vector-ref!} operators that we defined
-for tuples become overloaded for use with arrays.
+for tuples become overloaded for use with arrays.}
+\python{
+The subscript operator becomes overloaded for use with arrays and tuples
+and now may appear on the left-hand side of an assignment.
+Note that the index of the subscript may be an arbitrary expression
+and not just a constant integers.
+The \code{len} function is also applicable to arrays.
+}
 %
-We also include integer multiplication in \LangArray{}, as it is
+We include integer multiplication in \LangArray{}, as it is
 useful in many examples involving arrays such as computing the
-inner-product of two arrays (Figure~\ref{fig:inner-product}).
+inner product of two arrays (Figure~\ref{fig:inner_product}).
 
 \newcommand{\LarrayGrammarRacket}{
 \begin{array}{lcl}
   \Type &::=& \LP \key{Vectorof}~\Type \RP \\
   \Exp &::=& \CMUL{\Exp}{\Exp}
-       \MID \CMAKEVEC{\Exp}{\Exp} \\
+       \MID \CMAKEVEC{\Exp}{\Exp} 
+\end{array}
+}
+\newcommand{\LarrayASTRacket}{
+\begin{array}{lcl}
+  \Type &::=& \LP \key{Vectorof}~\Type \RP \\
+  \Exp &::=& \MUL{\Exp}{\Exp}
+       \MID \MAKEVEC{\Exp}{\Exp} 
+\end{array}
+}
+
+\newcommand{\LarrayGrammarPython}{
+\begin{array}{lcl}
+  \Type &::=& \key{list}\LS\Type\RS \\
+  \Exp &::=& \CMUL{\Exp}{\Exp}
+    \MID \CGET{\Exp}{\Exp}
+    \MID \LS \Exp \code{,} \ldots \RS \\
+  \Stmt &::= & \CGET{\Exp}{\Exp} \mathop{\key{=}}\Exp
+\end{array}
+}
+\newcommand{\LarrayASTPython}{
+\begin{array}{lcl}
+  \Type &::=& \key{ListType}\LP\Type\RP \\
+  \Exp &::=& \MUL{\Exp}{\Exp}
+    \MID \GET{\Exp}{\Exp} \\
+    &\MID& \key{List}\LP \Exp \code{,} \ldots \code{, } \code{Load()} \RP \\
+  \Stmt &::= & \ASSIGN{ \PUT{\Exp}{\Exp} }{\Exp}
 \end{array}
 }
 
@@ -12772,43 +12816,102 @@ inner-product of two arrays (Figure~\ref{fig:inner-product}).
 \]
 \fi}
 {\if\edition\pythonEd    
-UNDER CONSTRUCTION
+\[
+\begin{array}{l}
+  \gray{\LintGrammarPython{}} \\ \hline
+  \gray{\LvarGrammarPython{}} \\ \hline
+  \gray{\LifGrammarPython{}} \\ \hline
+  \gray{\LwhileGrammarPython} \\ \hline
+  \gray{\LtupGrammarPython} \\ \hline
+  \LarrayGrammarPython \\
+\begin{array}{rcl}
+  \LangArrayM{} &::=& \Stmt^{*}
+\end{array}
+\end{array}
+\]
 \fi}
 \end{tcolorbox}
-\caption{The concrete syntax of \LangArray{}, extending \LangLoop{} (Figure~\ref{fig:Lwhile-concrete-syntax}).}
+\caption{The concrete syntax of \LangArray{}, extending \LangVec{} (Figure~\ref{fig:Lvec-concrete-syntax}).}
 \label{fig:Lvecof-concrete-syntax}
 \end{figure}
 
+\begin{figure}[tp]
+\centering
+\begin{tcolorbox}[colback=white]
+    \small
+{\if\edition\racketEd    
+\[
+\begin{array}{l}
+  \gray{\LintASTRacket{}} \\ \hline
+  \gray{\LvarASTRacket{}} \\ \hline
+  \gray{\LifASTRacket{}} \\ \hline
+  \gray{\LwhileASTRacket} \\ \hline
+  \gray{\LtupASTRacket} \\ \hline
+  \LarrayASTRacket \\
+\begin{array}{lcl}
+  \LangArray{} &::=& \Exp
+\end{array}
+\end{array}
+\]
+\fi}
+{\if\edition\pythonEd    
+\[
+\begin{array}{l}
+  \gray{\LintASTPython{}} \\ \hline
+  \gray{\LvarASTPython{}} \\ \hline
+  \gray{\LifASTPython{}} \\ \hline
+  \gray{\LwhileASTPython} \\ \hline
+  \gray{\LtupASTPython} \\ \hline
+  \LarrayASTPython \\
+\begin{array}{rcl}
+  \LangArrayM{} &::=& \Stmt^{*}
+\end{array}
+\end{array}
+\]
+\fi}
+\end{tcolorbox}
+\caption{The abstract syntax of \LangArray{}, extending \LangVec{} (Figure~\ref{fig:Lvec-syntax}).}
+\label{fig:Lvecof-syntax}
+\end{figure}
+
 
 \begin{figure}[tp]
 \begin{tcolorbox}[colback=white]  
+{\if\edition\racketEd
+% TODO: remove the function from the following example, like the python version -Jeremy    
 \begin{lstlisting}
-(define (inner-product [A : (Vectorof Integer)] [B : (Vectorof Integer)]
-                          [n : Integer]) : Integer
-  (let ([i 0])
-    (let ([prod 0])
-      (begin
-        (while (< i n)
-          (begin
-            (set! prod (+ prod (* (vector-ref A i)
-                                  (vector-ref B i))))
-            (set! i (+ i 1))
-            ))
-        prod))))
-  
-
 (let ([A (make-vector 2 2)])
-  (let ([B (make-vector 2 3)])
-    (+ (inner-product A B 2)
-       30)))
+(let ([B (make-vector 2 3)])
+(let ([i 0])
+(let ([prod 0])
+(begin
+  (while (< i n)
+    (begin
+      (set! prod (+ prod (* (vector-ref A i)
+                            (vector-ref B i))))
+      (set! i (+ i 1))))
+  prod)))))
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd    
+\begin{lstlisting}
+A = [2, 2]
+B = [3, 3]
+i = 0
+prod = 0
+while i != len(A):
+  prod =  prod + A[i] * B[i]
+  i = i + 1
+print( prod )
+\end{lstlisting}
+\fi}
 \end{tcolorbox}
 
-\caption{Example program that computes the inner-product.}
-\label{fig:inner-product}
+\caption{Example program that computes the inner product.}
+\label{fig:inner_product}
 \end{figure}
 
-
+{\if\edition\racketEd
 The type checker for \LangArray{} is defined in
 Figure~\ref{fig:type-check-Lvecof}. The result type of
 \code{make-vector} is \code{(Vectorof T)} where \code{T} is the type
@@ -12821,9 +12924,23 @@ updated to handle the situation where the vector has type
 between operations on tuples versus arrays. We override the
 \code{operator-types} method to provide the type signature for
 multiplication: it takes two integers and returns an integer.
+\fi}
+{\if\edition\pythonEd    
+%
+The type checker for \LangArray{} is defined in
+Figure~\ref{fig:type-check-Lvecof}. The result type of a list literal
+is \code{list[T]} where \code{T} is the type of the initializing
+expressions.  The type checking of the \code{len} function and the
+subscript operator is updated to handle lists. The type checker now
+also handles a subscript on the left-hand side of an assignment.
+Regarding multiplication, it takes two integers and returns an
+integer.
+%
+\fi}
 
 \begin{figure}[tbp]
   \begin{tcolorbox}[colback=white]
+{\if\edition\racketEd    
     \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 (define type-check-Lvecof-class
   (class type-check-Lvec-class
@@ -12871,7 +12988,74 @@ multiplication: it takes two integers and returns an integer.
 
 (define (type-check-Lvecof p)
   (send (new type-check-Lvecof-class) type-check-program p))
+    \end{lstlisting}
+    \fi}
+{\if\edition\pythonEd    
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
+class TypeCheckLarray(TypeCheckLtup):
+  def type_check_exp(self, e, env):
+    match e:
+      case ast.List(es, Load()):
+        ts = [self.type_check_exp(e, env) for e in es]
+        elt_ty = ts[0]
+        for (ty, elt) in zip(ts, es):
+            self.check_type_equal(elt_ty, ty, elt)
+        e.has_type = ListType(elt_ty)
+        return e.has_type
+      case Call(Name('len'), [tup]):
+        tup_t = self.type_check_exp(tup, env)
+        tup.has_type = tup_t
+        match tup_t:
+          case TupleType(ts):
+            return IntType()
+          case ListType(ty):
+            return IntType()
+          case _:
+            raise Exception('len expected a tuple, not ' + repr(tup_t))
+      case Subscript(tup, index, Load()):
+        tup_ty = self.type_check_exp(tup, env)
+        index_ty = self.type_check_exp(index, env)
+        self.check_type_equal(index_ty, IntType(), index)
+        match tup_ty:
+          case TupleType(ts):
+            match index:
+              case Constant(i):
+                return ts[i]
+              case _:
+                raise Exception('subscript required constant integer index')
+          case ListType(ty):
+            return ty
+          case _:
+            raise Exception('subscript expected a tuple, not ' + repr(tup_ty))
+      case BinOp(left, Mult(), right):
+        l = self.type_check_exp(left, env)
+        self.check_type_equal(l, IntType(), left)
+        r = self.type_check_exp(right, env)
+        self.check_type_equal(r, IntType(), right)
+        return IntType()
+      case _:
+        return super().type_check_exp(e, env)
+
+  def type_check_stmts(self, ss, env):
+    if len(ss) == 0:
+      return VoidType()
+    match ss[0]:
+      case Assign([Subscript(tup, index, Store())], value):
+        tup_t = self.type_check_exp(tup, env)
+        value_t = self.type_check_exp(value, env)
+        index_ty = self.type_check_exp(index, env)
+        self.check_type_equal(index_ty, IntType(), index)
+        match tup_t:
+          case ListType(ty):
+            self.check_type_equal(ty, value_t, ss[0])          
+          case _:
+            raise Exception('type_check_stmts: expected a list, not ' \
+                            + repr(tup_t))
+        return self.type_check_stmts(ss[1:], env)
+      case _:
+        return super().type_check_stmts(ss, env)
 \end{lstlisting}
+\fi}
   \end{tcolorbox}
 
   \caption{Type checker for the \LangArray{} language.}
@@ -12879,14 +13063,22 @@ multiplication: it takes two integers and returns an integer.
 \end{figure}
 
 The interpreter for \LangArray{} is defined in
-Figure~\ref{fig:interp-Lvecof}.  The \code{make-vector} operator is
+Figure~\ref{fig:interp-Lvecof}.
+\racket{The \code{make-vector} operator is
 implemented with Racket's \code{make-vector} function and
 multiplication is \code{fx*}, multiplication for \code{fixnum}
-integers.
+integers.}
+%
+\python{We implement list creation with a Python list comprehension
+  and multiplication is implemented with Python multiplication.  We
+  add a case to handle a subscript on the left-hand side of
+  assignment. Other uses of subscript can be handled by the existing
+  code for tuples.}
 
 \begin{figure}[tbp]
   \begin{tcolorbox}[colback=white]
-    \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
+{\if\edition\racketEd    
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 (define interp-Lvecof-class
   (class interp-Lvec-class
     (super-new)
@@ -12901,6 +13093,34 @@ integers.
 (define (interp-Lvecof p)
   (send (new interp-Lvecof-class) interp-program p))
 \end{lstlisting}
+    \fi}
+{\if\edition\pythonEd
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
+class InterpLarray(InterpLtup):
+
+  def interp_exp(self, e, env):
+    match e:
+      case ast.List(es, Load()):
+        return [self.interp_exp(e, env) for e in es]
+      case BinOp(left, Mult(), right):
+          l = self.interp_exp(left, env); r = self.interp_exp(right, env)
+          return l * r
+      case _:
+        return super().interp_exp(e, env)
+
+  def interp_stmts(self, ss, env):
+    if len(ss) == 0:
+      return
+    match ss[0]:
+      case Assign([Subscript(lst, index)], value):
+        lst = self.interp_exp(lst, env)
+        index = self.interp_exp(index, env)
+        lst[index] = self.interp_exp(value, env)
+        return self.interp_stmts(ss[1:], env)
+      case _:
+        return super().interp_stmts(ss, env)
+\end{lstlisting}
+\fi}
   \end{tcolorbox}
 
   \caption{Interpreter for \LangArray{}.}
@@ -12951,9 +13171,9 @@ the passes to handle arrays.
 \subsection{Bounds Checking}
 
 We recommend inserting a new pass named \code{check\_bounds} that
-inserts code around each the \code{vector-ref} and \code{vector-set!}
-operation to ensure that the index is greater than or equal to zero
-and less than the \code{vector-length}.
+inserts code around each the \racket{\code{vector-ref} and \code{vector-set!}}
+\python{subscript} operation to ensure that the index is greater than or equal to zero
+and less than the array's length.
 
 %% \subsection{Reveal Casts}
 
@@ -13037,13 +13257,14 @@ statement, so make sure to handle both situations in this pass.
 
 Implement a compiler for the \LangArray{} language by extending your
 compiler for \LangLoop{}. Test your compiler on a half dozen new
-programs, including the one in Figure~\ref{fig:inner-product} and also
+programs, including the one in Figure~\ref{fig:inner_product} and also
 a program that multiplies two matrices. Note that although matrices
 are 2-dimensional arrays, they can be encoded into 1-dimensional
 arrays by laying out each row in the array, one after the next.
   
 \end{exercise}
 
+{\if\edition\racketEd
 \section{Challenge: Generational Collection}
 
 The copying collector described in Section~\ref{sec:GC} can incur
@@ -18647,7 +18868,7 @@ because the two types are consistent.
 \end{lstlisting}
 \fi}
 {\if\edition\pythonEd
-\begin{lstlisting}
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
   def consistent(self, t1, t2):
       match (t1, t2):
         case (AnyType(), _):
@@ -19302,29 +19523,47 @@ wrapping \code{maybe\_inc} in a new function that casts its parameter
 from \INTTY{} to \CANYTY{}, applies \code{maybe\_inc}, and then
 casts the return value from \CANYTY{} to \code{Integer}.
 
-UNDER CONSTRUCTION
 
-Turning our attention to casts involving tuple types, we consider the
-example in Figure~\ref{fig:map-bang} that defines a
-partially-typed version of \code{map} whose parameter \code{v} has
-type \code{(Vector Any Any)} and that updates \code{v} in place
+{\if\edition\pythonEd
+%
+Casts that involve mutable data require special care. So to
+demonstrate these issues, we use the \code{list} type introduced in
+the challenge assignment of Section~\ref{sec:arrays}.
+%
+\fi}
+%
+Turning our attention to casts involving \racket{tuple}\python{list}
+types, we consider the example in Figure~\ref{fig:map-bang} that
+defines a partially-typed version of \code{map} whose parameter
+\code{v} has type \racket{\code{(Vector Any
+    Any)}}\python{\code{list[Any]}} and that updates \code{v} in place
 instead of returning a new tuple. So we name this function
-\code{map!}. We apply \code{map!} to a tuple of integers, so
-the type checker inserts a cast from \code{(Vector Integer Integer)}
-to \code{(Vector Any Any)}. A naive way for the \LangCast{} interpreter to
-cast between tuple types would be a build a new tuple whose elements
-are the result of casting each of the original elements to the
-appropriate target type. However, this approach is only valid for
-immutable tuples; and our tuples are mutable. In the example of
-Figure~\ref{fig:map-bang}, if the cast created a new tuple, then
-the updates inside of \code{map!} would happen to the new tuple
-and not the original one.
+\code{map\_inplace}. We apply \code{map\_inplace} to a
+\racket{tuple}\python{list} of integers, so the type checker inserts a
+cast from
+\racket{\code{(Vector Integer Integer)}}
+\python{\code{list[int]}}
+to
+\racket{\code{(Vector Any Any)}}
+\python{\code{list[Any]}}.
+A naive way for the \LangCast{} interpreter to cast between
+\racket{tuple}\python{list} types would be a build a new
+\racket{tuple}\python{list}
+whose elements are the result
+of casting each of the original elements to the appropriate target
+type.
+However, this approach is not valid for mutable data structures.
+In the example of Figure~\ref{fig:map-bang},
+if the cast created a new \racket{tuple}\python{list}, then the updates inside of
+\code{map\_inplace} would happen to the new \racket{tuple}\python{list} and not
+the original one.
 
 \begin{figure}[tbp]
   \begin{tcolorbox}[colback=white]
     % gradual_test_11.rkt
+{\if\edition\racketEd
 \begin{lstlisting}
-(define (map! [f : (Any -> Any)]
+(define (map_inplace [f : (Any -> Any)]
                   [v : (Vector Any Any)]) : Void
   (begin
     (vector-set! v 0 (f (vector-ref v 0)))
@@ -19333,8 +19572,25 @@ and not the original one.
 (define (inc x) (+ x 1))
 
 (let ([v (vector 0 41)])
-  (begin (map! inc v) (vector-ref v 1)))
+  (begin (map_inplace inc v) (vector-ref v 1)))
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+\begin{lstlisting}
+def map_inplace(f : Callable[[Any], Any], v : list[Any]) -> None:
+  i = 0
+  while i != len(v):
+    v[i] = f(v[i])
+    i = i + 1
+
+def inc(x):
+    return x + 1
+
+v = [0, 41]
+map_inplace(inc, v)
+print( v[1] )
+\end{lstlisting}
+\fi}
   \end{tcolorbox}
 
   \caption{An example involving casts on vectors.}
@@ -19342,31 +19598,43 @@ and not the original one.
 \end{figure}
 
 Instead the interpreter needs to create a new kind of value, a
-\emph{tuple proxy}, that intercepts every tuple operation. On a
-read, the proxy reads from the underlying tuple and then applies a
+\emph{proxy}, that intercepts every \racket{tuple}\python{list} operation.
+On a read, the proxy reads from the underlying \racket{tuple}\python{list}
+and then applies a
 cast to the resulting value.  On a write, the proxy casts the argument
-value and then performs the write to the underlying tuple. For the
-first \code{(vector-ref v 0)} in \code{map!}, the proxy casts
-\code{0} from \code{Integer} to \CANYTY{}.  For the first
-\code{vector-set!}, the proxy casts a tagged \code{1} from \CANYTY{}
-to \code{Integer}.
+value and then performs the write to the underlying tuple.
+\racket{
+For the first \code{(vector-ref v 0)} in \code{map\_inplace}, the proxy casts
+\code{0} from \code{Integer} to \CANYTY{}.
+For the first \code{vector-set!}, the proxy casts a tagged \code{1}
+from \CANYTY{} to \code{Integer}.
+}
+\python{
+  For the subscript \code{v[i]} in \code{f([v[i])} of \code{map\_inplace},
+  the proxy casts integer from \INTTY{} to \CANYTY{}.
+  Then for the subscript on the left of the assignment,
+  the proxy casts the tagged value from from \CANYTY{} to \INTTY{}.
+}
 
 The final category of cast that we need to consider are casts between
-the \CANYTY{} type and either a function or a tuple
-type. Figure~\ref{fig:map-any} shows a variant of \code{map!}
-in which parameter \code{v} does not have a type annotation, so it is
-given type \CANYTY{}. In the call to \code{map!}, the tuple has
-type \code{(Vector Integer Integer)} so the type checker inserts a
-cast from \code{(Vector Integer Integer)} to \CANYTY{}. A first
-thought is to use \code{Inject}, but that doesn't work because
-\code{(Vector Integer Integer)} is not a flat type. Instead, we must
-first cast to \code{(Vector Any Any)} (which is flat) and then inject
-to \CANYTY{}.
+the \CANYTY{} type and higher-order types such as functions or
+\racket{tuples}\python{lists}. Figure~\ref{fig:map-any} shows a
+variant of \code{map\_inplace} in which parameter \code{v} does not
+have a type annotation, so it is given type \CANYTY{}. In the call to
+\code{map\_inplace}, the \racket{tuple}\python{list} has type
+\racket{\code{(Vector Integer Integer)}}\python{\code{list[int]}}
+so the type checker inserts a cast to \CANYTY{}. A first thought is to use
+\code{Inject}, but that doesn't work because
+\racket{\code{(Vector Integer Integer)}}\python{\code{list[int]}} is not
+a flat type. Instead, we must first cast to
+\racket{\code{(Vector Any Any)}}\python{\code{list[Any]}} (which is flat)
+and then inject to \CANYTY{}.
 
 \begin{figure}[tbp]
   \begin{tcolorbox}[colback=white]
+{\if\edition\racketEd
 \begin{lstlisting}
-(define (map! [f : (Any -> Any)] v) : Void
+(define (map_inplace [f : (Any -> Any)] v) : Void
   (begin
     (vector-set! v 0 (f (vector-ref v 0)))
     (vector-set! v 1 (f (vector-ref v 1)))))
@@ -19374,23 +19642,41 @@ to \CANYTY{}.
 (define (inc x) (+ x 1))
 
 (let ([v (vector 0 41)])
-  (begin (map! inc v) (vector-ref v 1)))
+  (begin (map_inplace inc v) (vector-ref v 1)))
+\end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+\begin{lstlisting}
+def map_inplace(f : Callable[[Any], Any], v) -> None:
+  i = 0
+  while i != len(v):
+    v[i] = f(v[i])
+    i = i + 1
+
+def inc(x):
+    return x + 1
+
+v v = [0, 41]
+map_inplace(inc, v)
+print( v[1] )
 \end{lstlisting}
+\fi}
   \end{tcolorbox}
 
-  \caption{Casting a tuple to \CANYTY{}.}
+  \caption{Casting a \racket{tuple}\python{list} to \CANYTY{}.}
 \label{fig:map-any}
 \end{figure}
 
 The \LangCast{} interpreter uses an auxiliary function named
-\code{apply-cast} to cast a value from a source type to a target type,
-shown in Figure~\ref{fig:apply-cast}. You'll find that it handles all
+\code{apply\_cast} to cast a value from a source type to a target type,
+shown in Figure~\ref{fig:apply_cast}. You'll find that it handles all
 of the kinds of casts that we've discussed in this section.
 
 \begin{figure}[tbp]
-\begin{tcolorbox}[colback=white]  
+  \begin{tcolorbox}[colback=white]
+{\if\edition\racketEd    
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
-(define/public (apply-cast v s t)
+(define/public (apply_cast v s t)
   (match* (s t)
     [(t1 t2) #:when (equal? t1 t2) v]
     [('Any t2) 
@@ -19398,21 +19684,21 @@ of the kinds of casts that we've discussed in this section.
        [`(,ts ... -> ,rt)
         (define any->any `(,@(for/list ([t ts]) 'Any) -> Any))
         (define v^ (apply-project v any->any))
-        (apply-cast v^ any->any `(,@ts -> ,rt))]
+        (apply_cast v^ any->any `(,@ts -> ,rt))]
        [`(Vector ,ts ...)
         (define vec-any `(Vector ,@(for/list ([t ts]) 'Any)))
         (define v^ (apply-project v vec-any))
-        (apply-cast v^ vec-any `(Vector ,@ts))]
+        (apply_cast v^ vec-any `(Vector ,@ts))]
        [else (apply-project v t2)])]
     [(t1 'Any) 
      (match t1
        [`(,ts ... -> ,rt)
         (define any->any `(,@(for/list ([t ts]) 'Any) -> Any))
-        (define v^ (apply-cast v `(,@ts -> ,rt) any->any))
+        (define v^ (apply_cast v `(,@ts -> ,rt) any->any))
         (apply-inject v^ (any-tag any->any))]
        [`(Vector ,ts ...)
         (define vec-any `(Vector ,@(for/list ([t ts]) 'Any)))
-        (define v^ (apply-cast v `(Vector ,@ts) vec-any))
+        (define v^ (apply_cast v `(Vector ,@ts) vec-any))
         (apply-inject v^ (any-tag vec-any))]
        [else (apply-inject v (any-tag t1))])]
     [(`(Vector ,ts1 ...) `(Vector ,ts2 ...))
@@ -19433,19 +19719,26 @@ of the kinds of casts that we've discussed in this section.
                       rt1 rt2) ())]
     ))
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
+UNDER CONSTRUCTION
+\end{lstlisting}
+\fi}
 \end{tcolorbox}
-\caption{The \code{apply-cast} auxiliary method.}
-  \label{fig:apply-cast}
+\caption{The \code{apply\_cast} auxiliary method.}
+  \label{fig:apply_cast}
 \end{figure}
 
 The interpreter for \LangCast{} is defined in
 Figure~\ref{fig:interp-Lcast}, with the case for \code{Cast}
-dispatching to \code{apply-cast}. To handle the addition of tuple
+dispatching to \code{apply\_cast}. To handle the addition of tuple
 proxies, we update the tuple primitives in \code{interp-op} using the
 functions in Figure~\ref{fig:guarded-tuple}.
 
 \begin{figure}[tbp]
 \begin{tcolorbox}[colback=white]  
+{\if\edition\racketEd    
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 (define interp-Lcast-class
   (class interp-Llambda-class
@@ -19473,13 +19766,19 @@ functions in Figure~\ref{fig:guarded-tuple}.
       (define (recur e) ((interp-exp env) e))
       (match e
         [(Value v) v]
-        [(Cast e src tgt) (apply-cast (recur e) src tgt)]
+        [(Cast e src tgt) (apply_cast (recur e) src tgt)]
         [else ((super interp-exp env) e)]))
     ))
 
 (define (interp-Lcast p)
   (send (new interp-Lcast-class) interp-program p))
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
+UNDER CONSTRUCTION
+\end{lstlisting}
+\fi}
 \end{tcolorbox}
 
 \caption{The interpreter for \LangCast{}.}
@@ -19489,6 +19788,7 @@ functions in Figure~\ref{fig:guarded-tuple}.
 
 \begin{figure}[tbp]
 \begin{tcolorbox}[colback=white]  
+{\if\edition\racketEd    
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
     (define (guarded-vector-ref vec i)
       (match vec
@@ -19512,6 +19812,12 @@ functions in Figure~\ref{fig:guarded-tuple}.
          (guarded-vector-length (vector-ref proxy 0))]
         [else (vector-length vec)]))
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
+UNDER CONSTRUCTION
+\end{lstlisting}
+\fi}
 \end{tcolorbox}
 
 \caption{The \code{guarded-vector} auxiliary functions.}
@@ -19520,9 +19826,9 @@ functions in Figure~\ref{fig:guarded-tuple}.
 
 
 \section{Lower Casts}
-\label{sec:lower-casts}
+\label{sec:lower_casts}
 
-The next step in the journey towards x86 is the \code{lower-casts}
+The next step in the journey towards x86 is the \code{lower\_casts}
 pass that translates the casts in \LangCast{} to the lower-level
 \code{Inject} and \code{Project} operators and a new operator for
 creating tuple proxies, extending the \LangLam{} language to create
@@ -19533,10 +19839,10 @@ the same behavior as casting the expression from the source to the
 target type in the interpreter.
 
 The \code{lower-cast} function can follow a code structure similar to
-the \code{apply-cast} function (Figure~\ref{fig:apply-cast}) used in
+the \code{apply\_cast} function (Figure~\ref{fig:apply_cast}) used in
 the interpreter for \LangCast{} because it must handle the same cases as
-\code{apply-cast} and it needs to mimic the behavior of
-\code{apply-cast}. The most interesting cases are those concerning the
+\code{apply\_cast} and it needs to mimic the behavior of
+\code{apply\_cast}. The most interesting cases are those concerning the
 casts between two tuple types and between two function types.
 
 As mentioned in Section~\ref{sec:interp-casts}, a cast from one tuple
@@ -19552,14 +19858,15 @@ see in the next section, we need to differentiate these tuples from
 the user-created ones, so we recommend using a new primitive operator
 named \code{raw-vector} instead of \code{vector} to create these
 tuples of functions. Figure~\ref{fig:map-bang-lower-cast} shows
-the output of \code{lower-casts} on the example in
+the output of \code{lower\_casts} on the example in
 Figure~\ref{fig:map-bang} that involved casting a tuple of
 integers to a tuple of \CANYTY{}.
 
 \begin{figure}[tbp]
 \begin{tcolorbox}[colback=white]  
+{\if\edition\racketEd    
 \begin{lstlisting}
-(define (map! [f : (Any -> Any)] [v : (Vector Any Any)]) : Void
+(define (map_inplace [f : (Any -> Any)] [v : (Vector Any Any)]) : Void
    (begin 
       (vector-set! v 0 (f (vector-ref v 0)))
       (vector-set! v 1 (f (vector-ref v 1)))))
@@ -19569,7 +19876,7 @@ integers to a tuple of \CANYTY{}.
 
 (let ([v (vector 0 41)])
    (begin 
-      (map! inc (vector-proxy v
+      (map_inplace inc (vector-proxy v
                         (raw-vector (lambda: ([x9 : Integer]) : Any
                                        (inject x9 Integer))
                                      (lambda: ([x9 : Integer]) : Any
@@ -19580,9 +19887,15 @@ integers to a tuple of \CANYTY{}.
                                        (project x9 Integer)))))
       (vector-ref v 1)))
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
+UNDER CONSTRUCTION
+\end{lstlisting}
+\fi}
 \end{tcolorbox}
 
-\caption{Output of \code{lower-casts} on the example in
+\caption{Output of \code{lower\_casts} on the example in
   Figure~\ref{fig:map-bang}.}
 \label{fig:map-bang-lower-cast}
 \end{figure}
@@ -19595,12 +19908,13 @@ backwards! Functions are contravariant\index{subject}{contravariant}
 in the parameters.). Afterwards, call the underlying function and then
 cast the result from the source return type to the target return type.
 Figure~\ref{fig:map-lower-cast} shows the output of the
-\code{lower-casts} pass on the \code{map} example in
+\code{lower\_casts} pass on the \code{map} example in
 Figure~\ref{fig:gradual-map}. Note that the \code{inc} argument in the
 call to \code{map} is wrapped in a \code{lambda}.
 
 \begin{figure}[tbp]
 \begin{tcolorbox}[colback=white]  
+{\if\edition\racketEd    
 \begin{lstlisting}
 (define (map [f : (Integer -> Integer)]
                    [v : (Vector Integer Integer)])
@@ -19614,9 +19928,15 @@ call to \code{map} is wrapped in a \code{lambda}.
                         (project (inc (inject x9 Integer)) Integer))
                       (vector 0 41)) 1)
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
+UNDER CONSTRUCTION
+\end{lstlisting}
+\fi}
 \end{tcolorbox}
 
-\caption{Output of \code{lower-casts} on the example in
+\caption{Output of \code{lower\_casts} on the example in
   Figure~\ref{fig:gradual-map}.}
 \label{fig:map-lower-cast}
 \end{figure}

+ 6 - 2
defs.tex

@@ -64,7 +64,8 @@
 \newcommand{\LangCLoop}{$\CLang_{\circlearrowleft}$} %C7
 \newcommand{\LangCLoopM}{\CLang_{\circlearrowleft}} %C7
 \newcommand{\LangLoopANF}{\ensuremath{\Lang^{\RCO}_{\mathsf{While}}}} %R8
-\newcommand{\LangArray}{\ensuremath{\Lang^{\mathsf{Array}}_{\mathsf{While}}}} %\Lang^s3
+\newcommand{\LangArray}{\ensuremath{\Lang_{\mathsf{Array}}}} %\Lang^s3
+\newcommand{\LangArrayM}{\Lang_{\mathsf{Array}}} %\Lang^s3
 \newcommand{\LangGrad}{$\Lang_{\mathsf{?}}$} %R9
 \newcommand{\LangGradM}{\Lang_{\mathsf{?}}} %R9
 \newcommand{\LangCast}{$\Lang_{\mathsf{Cast}}$} %R9'
@@ -241,6 +242,8 @@
 \newcommand{\CLOSURE}[2]{\key{Closure}\LP#1\code{, }#2\RP}
 \newcommand{\ARITY}[1]{\key{Call}\LP\key{Name}\LP\code{'arity'}\RP \code{, }\LS#1\RS\RP}
 \newcommand{\CARITY}[1]{\key{arity}\LP#1\RP}
+\newcommand{\CMUL}[2]{#1~\key{*}~#2}
+\newcommand{\MUL}[2]{{\key{BinOp}\LP #1\code{,} \key{Mult()}\key{,}#2\code{)}}}
 \fi % pythonEd
 
 \if\edition\racketEd
@@ -254,12 +257,13 @@
 \newcommand{\FUNREF}[2]{\LP\key{FunRef}~#1~#2\RP}
 \newcommand{\CFUNREF}[2]{\LP\key{fun-ref}~#1~#2\RP}
 \newcommand{\CLOSURE}[2]{\LP\key{Closure}~#1~#2\RP}
+\newcommand{\CMUL}[2]{\LP\key{*}~#1~#2\RP}
+\newcommand{\MUL}[2]{{\key{(Prim}~\code{'*}~\code{(}#1~#2\code{))}}}
 \fi
 \newcommand{\PRIM}[2]{\LP\key{Prim}~#1~\LP #2\RP\RP}
 \newcommand{\PROGRAMDEFSEXP}[3]{\code{(ProgramDefsExp}~#1~#2~#3\code{)}}
 \newcommand{\PROGRAMDEFS}[2]{\code{(ProgramDefs}~#1~#2\code{)}}
 \newcommand{\CADD}[2]{\LP\key{+}~#1~#2\RP}
-\newcommand{\CMUL}[2]{\LP\key{*}~#1~#2\RP}
 \newcommand{\CSUB}[2]{\LP\key{-}~#1~#2\RP}
 \newcommand{\CWHILE}[2]{\LP\key{while}~#1~#2\RP}
 \newcommand{\WHILE}[2]{\LP\key{WhileLoop}~#1~#2\RP}