Prechádzať zdrojové kódy

Merge branch 'IUCompilerCourse:master' into master

Programming Languages Uni Freiburg 3 rokov pred
rodič
commit
d89e107e90
2 zmenil súbory, kde vykonal 460 pridanie a 121 odobranie
  1. 445 118
      book.tex
  2. 15 3
      defs.tex

+ 445 - 118
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
 % TODO: create an interpreter for L_struct
 
 
 \clearpage
 \clearpage
+\fi}
 
 
 \section{Challenge: Arrays}
 \section{Challenge: Arrays}
 \label{sec: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
 sequences of elements whose length is determined at compile-time. This
 challenge is also about sequences, but this time the length is
 challenge is also about sequences, but this time the length is
 determined at run-time and all the elements have the same type (they
 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
 are homogeneous). We use the term ``array'' for this later kind of
 sequence.
 sequence.
-
+%
+\racket{
 The Racket language does not distinguish between tuples and arrays,
 The Racket language does not distinguish between tuples and arrays,
 they are both represented by vectors. However, Typed Racket
 they are both represented by vectors. However, Typed Racket
 distinguishes between tuples and arrays: the \code{Vector} type is for
 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
 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
 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
 \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
 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}{
 \newcommand{\LarrayGrammarRacket}{
 \begin{array}{lcl}
 \begin{array}{lcl}
   \Type &::=& \LP \key{Vectorof}~\Type \RP \\
   \Type &::=& \LP \key{Vectorof}~\Type \RP \\
   \Exp &::=& \CMUL{\Exp}{\Exp}
   \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}
 \end{array}
 }
 }
 
 
@@ -12772,43 +12816,102 @@ inner-product of two arrays (Figure~\ref{fig:inner-product}).
 \]
 \]
 \fi}
 \fi}
 {\if\edition\pythonEd    
 {\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}
 \fi}
 \end{tcolorbox}
 \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}
 \label{fig:Lvecof-concrete-syntax}
 \end{figure}
 \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{figure}[tp]
 \begin{tcolorbox}[colback=white]  
 \begin{tcolorbox}[colback=white]  
+{\if\edition\racketEd
+% TODO: remove the function from the following example, like the python version -Jeremy    
 \begin{lstlisting}
 \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 ([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}
 \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}
 \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}
 \end{figure}
 
 
-
+{\if\edition\racketEd
 The type checker for \LangArray{} is defined in
 The type checker for \LangArray{} is defined in
 Figure~\ref{fig:type-check-Lvecof}. The result type of
 Figure~\ref{fig:type-check-Lvecof}. The result type of
 \code{make-vector} is \code{(Vectorof T)} where \code{T} is the type
 \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
 between operations on tuples versus arrays. We override the
 \code{operator-types} method to provide the type signature for
 \code{operator-types} method to provide the type signature for
 multiplication: it takes two integers and returns an integer.
 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{figure}[tbp]
   \begin{tcolorbox}[colback=white]
   \begin{tcolorbox}[colback=white]
+{\if\edition\racketEd    
     \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
     \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 (define type-check-Lvecof-class
 (define type-check-Lvecof-class
   (class type-check-Lvec-class
   (class type-check-Lvec-class
@@ -12871,7 +12988,74 @@ multiplication: it takes two integers and returns an integer.
 
 
 (define (type-check-Lvecof p)
 (define (type-check-Lvecof p)
   (send (new type-check-Lvecof-class) type-check-program 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}
 \end{lstlisting}
+\fi}
   \end{tcolorbox}
   \end{tcolorbox}
 
 
   \caption{Type checker for the \LangArray{} language.}
   \caption{Type checker for the \LangArray{} language.}
@@ -12879,14 +13063,22 @@ multiplication: it takes two integers and returns an integer.
 \end{figure}
 \end{figure}
 
 
 The interpreter for \LangArray{} is defined in
 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
 implemented with Racket's \code{make-vector} function and
 multiplication is \code{fx*}, multiplication for \code{fixnum}
 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{figure}[tbp]
   \begin{tcolorbox}[colback=white]
   \begin{tcolorbox}[colback=white]
-    \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
+{\if\edition\racketEd    
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 (define interp-Lvecof-class
 (define interp-Lvecof-class
   (class interp-Lvec-class
   (class interp-Lvec-class
     (super-new)
     (super-new)
@@ -12901,6 +13093,34 @@ integers.
 (define (interp-Lvecof p)
 (define (interp-Lvecof p)
   (send (new interp-Lvecof-class) interp-program p))
   (send (new interp-Lvecof-class) interp-program p))
 \end{lstlisting}
 \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}
   \end{tcolorbox}
 
 
   \caption{Interpreter for \LangArray{}.}
   \caption{Interpreter for \LangArray{}.}
@@ -12948,12 +13168,22 @@ an array:
 In the following subsections we provide hints regarding how to update
 In the following subsections we provide hints regarding how to update
 the passes to handle arrays.
 the passes to handle arrays.
 
 
+\subsection{Shrink}
+
+Translate calls to \racket{\code{vector-length}}\python{\code{len}}
+into a primitive specific to arrays, \racket{\code{vectorof-length}}\python{\code{array\_len}},
+when the argument's type is \CARRAYTY{T}.
+%
+\python{The type checker for \LangArray{} adds a \code{has\_type}
+  field to the argument of \code{len} for this purpose.}
+
+
 \subsection{Bounds Checking}
 \subsection{Bounds Checking}
 
 
 We recommend inserting a new pass named \code{check\_bounds} that
 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 \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}
 %% \subsection{Reveal Casts}
 
 
@@ -12989,16 +13219,13 @@ and less than the \code{vector-length}.
 
 
 \subsection{Expose Allocation}
 \subsection{Expose Allocation}
 
 
-This pass should translate the \code{make-vector} operator into
-lower-level operations. In particular, the new AST node
-$\LP\key{AllocateArray}~\Exp~\Type\RP$ is analogous to the
-\code{Allocate} AST node for tuples.  It allocates an array of the
-length specified by the $\Exp$, but does not initialize the elements
-of the array. The $\Type$ argument must be $\LP\key{Vectorof}~T\RP$
-where $T$ is the element type for the array. Regarding the
-initialization of the array, we recommend generated a \code{while}
-loop that uses \code{vector-set!} to put the initializing value into
-every element of the array.
+This pass should translate array creation into lower-level
+operations. In particular, the new AST node \ALLOCARRAY{\Exp}{\Type}
+is analogous to the \code{Allocate} AST node for tuples.  The $\Type$
+argument must be \ARRAYTY{T} where $T$ is the element type for the
+array. The \code{AllocateArray} AST node allocates an array of the
+length specified by the $\Exp$ but does not initialize the elements of
+the array. Generate code in this pass to initialize the elements.
 
 
 \subsection{Remove Complex Operands}
 \subsection{Remove Complex Operands}
 
 
@@ -13018,16 +13245,16 @@ Generate instructions for \code{AllocateArray} similar to those for
 that the tag at the front of the array should instead use the
 that the tag at the front of the array should instead use the
 representation discussed in Section~\ref{sec:array-rep}.
 representation discussed in Section~\ref{sec:array-rep}.
 
 
-Regarding \code{vectorof-length}, extract the length from the tag
-according to the representation discussed in
+Regarding \racket{\code{vectorof-length}}\python{\code{array\_len}},
+extract the length from the tag according to the representation discussed in
 Section~\ref{sec:array-rep}.
 Section~\ref{sec:array-rep}.
 
 
-The instructions generated for \code{vectorof-ref} differ from those
-for \code{vector-ref} (Section~\ref{sec:select-instructions-gc}) in
+The instructions generated for accessing an element of an array differ
+from those for a tuple (Section~\ref{sec:select-instructions-gc}) in
 that the index is not a constant so the offset must be computed at
 that the index is not a constant so the offset must be computed at
-runtime. The same is true for \code{vectorof-set!}.  Also, the
-\code{vectorof-set!} may appear in an assignment and as a stand-alone
-statement, so make sure to handle both situations in this pass.
+runtime. Also, note that assignment to an array element may appear in
+as a stand-alone statement, so make sure to handle that situation in
+this pass.
 
 
 %% Finally, the instructions for \code{any-vectorof-length} should be
 %% Finally, the instructions for \code{any-vectorof-length} should be
 %% similar to those for \code{vectorof-length}, except that one must
 %% similar to those for \code{vectorof-length}, except that one must
@@ -13037,13 +13264,14 @@ statement, so make sure to handle both situations in this pass.
 
 
 Implement a compiler for the \LangArray{} language by extending your
 Implement a compiler for the \LangArray{} language by extending your
 compiler for \LangLoop{}. Test your compiler on a half dozen new
 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
 a program that multiplies two matrices. Note that although matrices
 are 2-dimensional arrays, they can be encoded into 1-dimensional
 are 2-dimensional arrays, they can be encoded into 1-dimensional
 arrays by laying out each row in the array, one after the next.
 arrays by laying out each row in the array, one after the next.
   
   
 \end{exercise}
 \end{exercise}
 
 
+{\if\edition\racketEd
 \section{Challenge: Generational Collection}
 \section{Challenge: Generational Collection}
 
 
 The copying collector described in Section~\ref{sec:GC} can incur
 The copying collector described in Section~\ref{sec:GC} can incur
@@ -18651,7 +18879,7 @@ because the two types are consistent.
 \end{lstlisting}
 \end{lstlisting}
 \fi}
 \fi}
 {\if\edition\pythonEd
 {\if\edition\pythonEd
-\begin{lstlisting}
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
   def consistent(self, t1, t2):
   def consistent(self, t1, t2):
       match (t1, t2):
       match (t1, t2):
         case (AnyType(), _):
         case (AnyType(), _):
@@ -19306,29 +19534,47 @@ wrapping \code{maybe\_inc} in a new function that casts its parameter
 from \INTTY{} to \CANYTY{}, applies \code{maybe\_inc}, and then
 from \INTTY{} to \CANYTY{}, applies \code{maybe\_inc}, and then
 casts the return value from \CANYTY{} to \code{Integer}.
 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
 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{figure}[tbp]
   \begin{tcolorbox}[colback=white]
   \begin{tcolorbox}[colback=white]
     % gradual_test_11.rkt
     % gradual_test_11.rkt
+{\if\edition\racketEd
 \begin{lstlisting}
 \begin{lstlisting}
-(define (map! [f : (Any -> Any)]
+(define (map_inplace [f : (Any -> Any)]
                   [v : (Vector Any Any)]) : Void
                   [v : (Vector Any Any)]) : Void
   (begin
   (begin
     (vector-set! v 0 (f (vector-ref v 0)))
     (vector-set! v 0 (f (vector-ref v 0)))
@@ -19337,8 +19583,25 @@ and not the original one.
 (define (inc x) (+ x 1))
 (define (inc x) (+ x 1))
 
 
 (let ([v (vector 0 41)])
 (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}
 \end{lstlisting}
+\fi}
   \end{tcolorbox}
   \end{tcolorbox}
 
 
   \caption{An example involving casts on vectors.}
   \caption{An example involving casts on vectors.}
@@ -19346,31 +19609,43 @@ and not the original one.
 \end{figure}
 \end{figure}
 
 
 Instead the interpreter needs to create a new kind of value, a
 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
 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 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{figure}[tbp]
   \begin{tcolorbox}[colback=white]
   \begin{tcolorbox}[colback=white]
+{\if\edition\racketEd
 \begin{lstlisting}
 \begin{lstlisting}
-(define (map! [f : (Any -> Any)] v) : Void
+(define (map_inplace [f : (Any -> Any)] v) : Void
   (begin
   (begin
     (vector-set! v 0 (f (vector-ref v 0)))
     (vector-set! v 0 (f (vector-ref v 0)))
     (vector-set! v 1 (f (vector-ref v 1)))))
     (vector-set! v 1 (f (vector-ref v 1)))))
@@ -19378,23 +19653,41 @@ to \CANYTY{}.
 (define (inc x) (+ x 1))
 (define (inc x) (+ x 1))
 
 
 (let ([v (vector 0 41)])
 (let ([v (vector 0 41)])
-  (begin (map! inc v) (vector-ref v 1)))
+  (begin (map_inplace inc v) (vector-ref v 1)))
 \end{lstlisting}
 \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}
   \end{tcolorbox}
 
 
-  \caption{Casting a tuple to \CANYTY{}.}
+  \caption{Casting a \racket{tuple}\python{list} to \CANYTY{}.}
 \label{fig:map-any}
 \label{fig:map-any}
 \end{figure}
 \end{figure}
 
 
 The \LangCast{} interpreter uses an auxiliary function named
 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.
 of the kinds of casts that we've discussed in this section.
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
-\begin{tcolorbox}[colback=white]  
+  \begin{tcolorbox}[colback=white]
+{\if\edition\racketEd    
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
-(define/public (apply-cast v s t)
+(define/public (apply_cast v s t)
   (match* (s t)
   (match* (s t)
     [(t1 t2) #:when (equal? t1 t2) v]
     [(t1 t2) #:when (equal? t1 t2) v]
     [('Any t2) 
     [('Any t2) 
@@ -19402,21 +19695,21 @@ of the kinds of casts that we've discussed in this section.
        [`(,ts ... -> ,rt)
        [`(,ts ... -> ,rt)
         (define any->any `(,@(for/list ([t ts]) 'Any) -> Any))
         (define any->any `(,@(for/list ([t ts]) 'Any) -> Any))
         (define v^ (apply-project v 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 ...)
        [`(Vector ,ts ...)
         (define vec-any `(Vector ,@(for/list ([t ts]) 'Any)))
         (define vec-any `(Vector ,@(for/list ([t ts]) 'Any)))
         (define v^ (apply-project v vec-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)])]
        [else (apply-project v t2)])]
     [(t1 'Any) 
     [(t1 'Any) 
      (match t1
      (match t1
        [`(,ts ... -> ,rt)
        [`(,ts ... -> ,rt)
         (define any->any `(,@(for/list ([t ts]) 'Any) -> Any))
         (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))]
         (apply-inject v^ (any-tag any->any))]
        [`(Vector ,ts ...)
        [`(Vector ,ts ...)
         (define vec-any `(Vector ,@(for/list ([t ts]) 'Any)))
         (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))]
         (apply-inject v^ (any-tag vec-any))]
        [else (apply-inject v (any-tag t1))])]
        [else (apply-inject v (any-tag t1))])]
     [(`(Vector ,ts1 ...) `(Vector ,ts2 ...))
     [(`(Vector ,ts1 ...) `(Vector ,ts2 ...))
@@ -19437,19 +19730,26 @@ of the kinds of casts that we've discussed in this section.
                       rt1 rt2) ())]
                       rt1 rt2) ())]
     ))
     ))
 \end{lstlisting}
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
+UNDER CONSTRUCTION
+\end{lstlisting}
+\fi}
 \end{tcolorbox}
 \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}
 \end{figure}
 
 
 The interpreter for \LangCast{} is defined in
 The interpreter for \LangCast{} is defined in
 Figure~\ref{fig:interp-Lcast}, with the case for \code{Cast}
 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
 proxies, we update the tuple primitives in \code{interp-op} using the
 functions in Figure~\ref{fig:guarded-tuple}.
 functions in Figure~\ref{fig:guarded-tuple}.
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{tcolorbox}[colback=white]  
 \begin{tcolorbox}[colback=white]  
+{\if\edition\racketEd    
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 (define interp-Lcast-class
 (define interp-Lcast-class
   (class interp-Llambda-class
   (class interp-Llambda-class
@@ -19477,13 +19777,19 @@ functions in Figure~\ref{fig:guarded-tuple}.
       (define (recur e) ((interp-exp env) e))
       (define (recur e) ((interp-exp env) e))
       (match e
       (match e
         [(Value v) v]
         [(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)]))
         [else ((super interp-exp env) e)]))
     ))
     ))
 
 
 (define (interp-Lcast p)
 (define (interp-Lcast p)
   (send (new interp-Lcast-class) interp-program p))
   (send (new interp-Lcast-class) interp-program p))
 \end{lstlisting}
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
+UNDER CONSTRUCTION
+\end{lstlisting}
+\fi}
 \end{tcolorbox}
 \end{tcolorbox}
 
 
 \caption{The interpreter for \LangCast{}.}
 \caption{The interpreter for \LangCast{}.}
@@ -19493,6 +19799,7 @@ functions in Figure~\ref{fig:guarded-tuple}.
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{tcolorbox}[colback=white]  
 \begin{tcolorbox}[colback=white]  
+{\if\edition\racketEd    
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
     (define (guarded-vector-ref vec i)
     (define (guarded-vector-ref vec i)
       (match vec
       (match vec
@@ -19516,6 +19823,12 @@ functions in Figure~\ref{fig:guarded-tuple}.
          (guarded-vector-length (vector-ref proxy 0))]
          (guarded-vector-length (vector-ref proxy 0))]
         [else (vector-length vec)]))
         [else (vector-length vec)]))
 \end{lstlisting}
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
+UNDER CONSTRUCTION
+\end{lstlisting}
+\fi}
 \end{tcolorbox}
 \end{tcolorbox}
 
 
 \caption{The \code{guarded-vector} auxiliary functions.}
 \caption{The \code{guarded-vector} auxiliary functions.}
@@ -19524,9 +19837,9 @@ functions in Figure~\ref{fig:guarded-tuple}.
 
 
 
 
 \section{Lower Casts}
 \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
 pass that translates the casts in \LangCast{} to the lower-level
 \code{Inject} and \code{Project} operators and a new operator for
 \code{Inject} and \code{Project} operators and a new operator for
 creating tuple proxies, extending the \LangLam{} language to create
 creating tuple proxies, extending the \LangLam{} language to create
@@ -19537,10 +19850,10 @@ the same behavior as casting the expression from the source to the
 target type in the interpreter.
 target type in the interpreter.
 
 
 The \code{lower-cast} function can follow a code structure similar to
 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
 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.
 casts between two tuple types and between two function types.
 
 
 As mentioned in Section~\ref{sec:interp-casts}, a cast from one tuple
 As mentioned in Section~\ref{sec:interp-casts}, a cast from one tuple
@@ -19556,14 +19869,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
 the user-created ones, so we recommend using a new primitive operator
 named \code{raw-vector} instead of \code{vector} to create these
 named \code{raw-vector} instead of \code{vector} to create these
 tuples of functions. Figure~\ref{fig:map-bang-lower-cast} shows
 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
 Figure~\ref{fig:map-bang} that involved casting a tuple of
 integers to a tuple of \CANYTY{}.
 integers to a tuple of \CANYTY{}.
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{tcolorbox}[colback=white]  
 \begin{tcolorbox}[colback=white]  
+{\if\edition\racketEd    
 \begin{lstlisting}
 \begin{lstlisting}
-(define (map! [f : (Any -> Any)] [v : (Vector Any Any)]) : Void
+(define (map_inplace [f : (Any -> Any)] [v : (Vector Any Any)]) : Void
    (begin 
    (begin 
       (vector-set! v 0 (f (vector-ref v 0)))
       (vector-set! v 0 (f (vector-ref v 0)))
       (vector-set! v 1 (f (vector-ref v 1)))))
       (vector-set! v 1 (f (vector-ref v 1)))))
@@ -19573,7 +19887,7 @@ integers to a tuple of \CANYTY{}.
 
 
 (let ([v (vector 0 41)])
 (let ([v (vector 0 41)])
    (begin 
    (begin 
-      (map! inc (vector-proxy v
+      (map_inplace inc (vector-proxy v
                         (raw-vector (lambda: ([x9 : Integer]) : Any
                         (raw-vector (lambda: ([x9 : Integer]) : Any
                                        (inject x9 Integer))
                                        (inject x9 Integer))
                                      (lambda: ([x9 : Integer]) : Any
                                      (lambda: ([x9 : Integer]) : Any
@@ -19584,9 +19898,15 @@ integers to a tuple of \CANYTY{}.
                                        (project x9 Integer)))))
                                        (project x9 Integer)))))
       (vector-ref v 1)))
       (vector-ref v 1)))
 \end{lstlisting}
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
+UNDER CONSTRUCTION
+\end{lstlisting}
+\fi}
 \end{tcolorbox}
 \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}.}
   Figure~\ref{fig:map-bang}.}
 \label{fig:map-bang-lower-cast}
 \label{fig:map-bang-lower-cast}
 \end{figure}
 \end{figure}
@@ -19599,12 +19919,13 @@ backwards! Functions are contravariant\index{subject}{contravariant}
 in the parameters.). Afterwards, call the underlying function and then
 in the parameters.). Afterwards, call the underlying function and then
 cast the result from the source return type to the target return type.
 cast the result from the source return type to the target return type.
 Figure~\ref{fig:map-lower-cast} shows the output of the
 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
 Figure~\ref{fig:gradual-map}. Note that the \code{inc} argument in the
 call to \code{map} is wrapped in a \code{lambda}.
 call to \code{map} is wrapped in a \code{lambda}.
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{tcolorbox}[colback=white]  
 \begin{tcolorbox}[colback=white]  
+{\if\edition\racketEd    
 \begin{lstlisting}
 \begin{lstlisting}
 (define (map [f : (Integer -> Integer)]
 (define (map [f : (Integer -> Integer)]
                    [v : (Vector Integer Integer)])
                    [v : (Vector Integer Integer)])
@@ -19618,9 +19939,15 @@ call to \code{map} is wrapped in a \code{lambda}.
                         (project (inc (inject x9 Integer)) Integer))
                         (project (inc (inject x9 Integer)) Integer))
                       (vector 0 41)) 1)
                       (vector 0 41)) 1)
 \end{lstlisting}
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
+UNDER CONSTRUCTION
+\end{lstlisting}
+\fi}
 \end{tcolorbox}
 \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}.}
   Figure~\ref{fig:gradual-map}.}
 \label{fig:map-lower-cast}
 \label{fig:map-lower-cast}
 \end{figure}
 \end{figure}

+ 15 - 3
defs.tex

@@ -64,7 +64,8 @@
 \newcommand{\LangCLoop}{$\CLang_{\circlearrowleft}$} %C7
 \newcommand{\LangCLoop}{$\CLang_{\circlearrowleft}$} %C7
 \newcommand{\LangCLoopM}{\CLang_{\circlearrowleft}} %C7
 \newcommand{\LangCLoopM}{\CLang_{\circlearrowleft}} %C7
 \newcommand{\LangLoopANF}{\ensuremath{\Lang^{\RCO}_{\mathsf{While}}}} %R8
 \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{\LangGrad}{$\Lang_{\mathsf{?}}$} %R9
 \newcommand{\LangGradM}{\Lang_{\mathsf{?}}} %R9
 \newcommand{\LangGradM}{\Lang_{\mathsf{?}}} %R9
 \newcommand{\LangCast}{$\Lang_{\mathsf{Cast}}$} %R9'
 \newcommand{\LangCast}{$\Lang_{\mathsf{Cast}}$} %R9'
@@ -154,7 +155,9 @@
 \newcommand{\INTTY}{{\key{Integer}}}
 \newcommand{\INTTY}{{\key{Integer}}}
 \newcommand{\INTTYPE}{{\key{Integer}}}
 \newcommand{\INTTYPE}{{\key{Integer}}}
 \newcommand{\BOOLTY}{{\key{Boolean}}}
 \newcommand{\BOOLTY}{{\key{Boolean}}}
-\newcommand{\VECTY}[1]{{\LP\key{Vector}~#1\RP}}
+\newcommand{\VECTY}[1]{\LP\key{Vector}~#1\RP}
+\newcommand{\ARRAYTY}[1]{\LP\key{Vectorof}~#1\RP}
+\newcommand{\CARRAYTY}[1]{\LP\key{Vectorof}~#1\RP}
 \newcommand{\ANYTY}{{\key{Any}}}
 \newcommand{\ANYTY}{{\key{Any}}}
 \newcommand{\CANYTY}{{\key{Any}}}
 \newcommand{\CANYTY}{{\key{Any}}}
 \newcommand{\CPROGRAM}[2]{\LP\code{CProgram}~#1~#2\RP}
 \newcommand{\CPROGRAM}[2]{\LP\code{CProgram}~#1~#2\RP}
@@ -165,6 +168,8 @@
 \newcommand{\CCOLLECT}[1]{\LP\key{collect}~#1\RP}
 \newcommand{\CCOLLECT}[1]{\LP\key{collect}~#1\RP}
 \newcommand{\ALLOCATE}[2]{\LP\key{Allocate}~#1~#2\RP}
 \newcommand{\ALLOCATE}[2]{\LP\key{Allocate}~#1~#2\RP}
 \newcommand{\CALLOCATE}[2]{\LP\key{allocate}~#1~#2\RP}
 \newcommand{\CALLOCATE}[2]{\LP\key{allocate}~#1~#2\RP}
+\newcommand{\ALLOCARRAY}[2]{\LP\key{AllocateArray}~#1~#2\RP}
+\newcommand{\CALLOCARRAY}[2]{\LP\key{allocate\_array}~#1~#2\RP}
 \newcommand{\GLOBAL}[1]{\LP\key{Global}~#1\RP}
 \newcommand{\GLOBAL}[1]{\LP\key{Global}~#1\RP}
 \newcommand{\CGLOBAL}[1]{#1\key{(\%rip)}}
 \newcommand{\CGLOBAL}[1]{#1\key{(\%rip)}}
 \newcommand{\GLOBALVALUE}[1]{\LP\key{GlobalValue}~#1\RP}
 \newcommand{\GLOBALVALUE}[1]{\LP\key{GlobalValue}~#1\RP}
@@ -222,11 +227,15 @@
 \newcommand{\ANYTY}{{\key{AnyType}}}
 \newcommand{\ANYTY}{{\key{AnyType}}}
 \newcommand{\CANYTY}{{\key{Any}}}
 \newcommand{\CANYTY}{{\key{Any}}}
 \newcommand{\VECTY}[1]{{\key{TupleType}\LP\LS #1 \RS\RP}}
 \newcommand{\VECTY}[1]{{\key{TupleType}\LP\LS #1 \RS\RP}}
+\newcommand{\ARRAYTY}[1]{\key{ListType}\LP#1\RP}
+\newcommand{\CARRAYTY}[1]{\key{list}\LS#1\RS}
 \newcommand{\INTTYPE}{{\key{IntType}}}
 \newcommand{\INTTYPE}{{\key{IntType}}}
 \newcommand{\COLLECT}[1]{\key{Collect}\LP#1\RP}
 \newcommand{\COLLECT}[1]{\key{Collect}\LP#1\RP}
 \newcommand{\CCOLLECT}[1]{\key{collect}\LP#1\RP}
 \newcommand{\CCOLLECT}[1]{\key{collect}\LP#1\RP}
 \newcommand{\ALLOCATE}[2]{\key{Allocate}\LP#1,#2\RP}
 \newcommand{\ALLOCATE}[2]{\key{Allocate}\LP#1,#2\RP}
 \newcommand{\CALLOCATE}[2]{\key{allocate}\LP#1,#2\RP}
 \newcommand{\CALLOCATE}[2]{\key{allocate}\LP#1,#2\RP}
+\newcommand{\ALLOCARRAY}[2]{\key{AllocateArrow}\LP#1,#2\RP}
+\newcommand{\CALLOCARRAY}[2]{\key{allocate\_arrray}\LP#1,#2\RP}
 \newcommand{\GLOBALVALUE}[1]{\key{GlobalValue}\LP#1\RP}
 \newcommand{\GLOBALVALUE}[1]{\key{GlobalValue}\LP#1\RP}
 \newcommand{\CGLOBALVALUE}[1]{\key{global\_value}\LP#1\RP}
 \newcommand{\CGLOBALVALUE}[1]{\key{global\_value}\LP#1\RP}
 \newcommand{\GLOBAL}[1]{\key{Global}\LP#1\RP}
 \newcommand{\GLOBAL}[1]{\key{Global}\LP#1\RP}
@@ -241,6 +250,8 @@
 \newcommand{\CLOSURE}[2]{\key{Closure}\LP#1\code{, }#2\RP}
 \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{\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{\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
 \fi % pythonEd
 
 
 \if\edition\racketEd
 \if\edition\racketEd
@@ -254,12 +265,13 @@
 \newcommand{\FUNREF}[2]{\LP\key{FunRef}~#1~#2\RP}
 \newcommand{\FUNREF}[2]{\LP\key{FunRef}~#1~#2\RP}
 \newcommand{\CFUNREF}[2]{\LP\key{fun-ref}~#1~#2\RP}
 \newcommand{\CFUNREF}[2]{\LP\key{fun-ref}~#1~#2\RP}
 \newcommand{\CLOSURE}[2]{\LP\key{Closure}~#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
 \fi
 \newcommand{\PRIM}[2]{\LP\key{Prim}~#1~\LP #2\RP\RP}
 \newcommand{\PRIM}[2]{\LP\key{Prim}~#1~\LP #2\RP\RP}
 \newcommand{\PROGRAMDEFSEXP}[3]{\code{(ProgramDefsExp}~#1~#2~#3\code{)}}
 \newcommand{\PROGRAMDEFSEXP}[3]{\code{(ProgramDefsExp}~#1~#2~#3\code{)}}
 \newcommand{\PROGRAMDEFS}[2]{\code{(ProgramDefs}~#1~#2\code{)}}
 \newcommand{\PROGRAMDEFS}[2]{\code{(ProgramDefs}~#1~#2\code{)}}
 \newcommand{\CADD}[2]{\LP\key{+}~#1~#2\RP}
 \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{\CSUB}[2]{\LP\key{-}~#1~#2\RP}
 \newcommand{\CWHILE}[2]{\LP\key{while}~#1~#2\RP}
 \newcommand{\CWHILE}[2]{\LP\key{while}~#1~#2\RP}
 \newcommand{\WHILE}[2]{\LP\key{WhileLoop}~#1~#2\RP}
 \newcommand{\WHILE}[2]{\LP\key{WhileLoop}~#1~#2\RP}