瀏覽代碼

some progress

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

+ 98 - 71
book.tex

@@ -14140,7 +14140,7 @@ previously created test programs.
 \node (Rfun) at (0,2)  {\large \LangFun{}};
 \node (Rfun-1) at (3,2)  {\large \LangFun{}};
 \node (Rfun-2) at (6,2)  {\large \LangFun{}};
-\node (F1-1) at (12,0)  {\large \LangFunRef{}};
+\node (F1-1) at (9,2)  {\large \LangFunRef{}};
 \node (F1-2) at (9,0)  {\large \LangFunRef{}};
 \node (F1-3) at (6,0)  {\large \LangFunRefAlloc{}};
 \node (F1-4) at (3,0)  {\large \LangFunANF{}};
@@ -14158,9 +14158,9 @@ previously created test programs.
      {\ttfamily\footnotesize shrink} (Rfun-1);
 \path[->,bend left=15] (Rfun-1) edge [above] node
      {\ttfamily\footnotesize uniquify} (Rfun-2);
-\path[->,bend left=15] (Rfun-2) edge [right] node
+\path[->,bend left=15] (Rfun-2) edge [above] node
      {\ttfamily\footnotesize ~~reveal\_functions} (F1-1);
-\path[->,bend left=15] (F1-1) edge [below] node
+\path[->,bend left=15] (F1-1) edge [right] node
      {\ttfamily\footnotesize limit\_functions} (F1-2);
 \path[->,bend right=15] (F1-2) edge [above] node
      {\ttfamily\footnotesize expose\_alloc.} (F1-3);
@@ -14199,7 +14199,7 @@ function in \LangFun{} to x86. The figure also includes the results of the
 \begin{minipage}{0.4\textwidth}
 % s3_2.rkt
 {\if\edition\racketEd
-\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 (define (add [x : Integer] [y : Integer])
    : Integer
    (+ x y))
@@ -14207,7 +14207,7 @@ function in \LangFun{} to x86. The figure also includes the results of the
 \end{lstlisting}
 \fi}
 {\if\edition\pythonEd
-\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 def add(x:int, y:int) -> int:
     return x + y
 
@@ -14216,7 +14216,7 @@ print(add(40, 2))
 \fi}
 $\Downarrow$
 {\if\edition\racketEd
-\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 (define (add86 [x87 : Integer]
                  [y88 : Integer]) : Integer
    add86start:
@@ -14230,7 +14230,7 @@ $\Downarrow$
 \end{lstlisting}
 \fi}
 {\if\edition\pythonEd
-\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 def add(x:int, y:int) -> int:
     addstart:
         return x + y
@@ -14248,7 +14248,7 @@ def main() -> int:
 $\Rightarrow$
 \begin{minipage}{0.5\textwidth}
 {\if\edition\racketEd
-\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 (define (add86) : Integer
    add86start:
       movq %rdi, x87
@@ -14267,7 +14267,7 @@ $\Rightarrow$
 \end{lstlisting}
 \fi}
 {\if\edition\pythonEd
-\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 def add() -> int:
     addstart:
         movq %rdi, x
@@ -14295,7 +14295,7 @@ $\Downarrow$
 \begin{tabular}{ll}
 \begin{minipage}{0.3\textwidth}
 {\if\edition\racketEd
-\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 	.globl add86
 	.align 16
 add86:
@@ -14312,7 +14312,7 @@ add86conclusion:
 \end{lstlisting}
 \fi}
 {\if\edition\pythonEd
-\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
   .align 16
 add:
   pushq %rbp
@@ -14336,7 +14336,7 @@ addconclusion:
 &
 \begin{minipage}{0.5\textwidth}
 {\if\edition\racketEd
-\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 	.globl main
 	.align 16
 main:
@@ -14360,7 +14360,7 @@ mainconclusion:
 \end{lstlisting}
 \fi}
 {\if\edition\pythonEd
-\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
+\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
   .globl main
   .align 16
 main:
@@ -14571,6 +14571,8 @@ syntax for function application.
   \end{array}
 }
 
+% include AnnAssign in ASTPython
+
 \begin{figure}[tp]
 \centering
 \fbox{
@@ -14586,24 +14588,6 @@ syntax for function application.
   \gray{\LfunGrammarRacket} \\   \hline
   \LlambdaGrammarRacket \\
   \begin{array}{lcl}
-  %% \Type &::=& \gray{\key{Integer} \MID \key{Boolean}
-  %%    \MID (\key{Vector}\;\Type\ldots) \MID \key{Void}
-  %%    \MID (\Type\ldots \; \key{->}\; \Type)} \\
-  %% \Exp &::=& \gray{ \Int \MID \CREAD{} \MID \CNEG{\Exp}
-  %%    \MID \CADD{\Exp}{\Exp} \MID \CSUB{\Exp}{\Exp} }  \\
-  %%   &\MID&  \gray{ \Var \MID \CLET{\Var}{\Exp}{\Exp} }\\
-  %%   &\MID& \gray{\key{\#t} \MID \key{\#f} 
-  %%    \MID (\key{and}\;\Exp\;\Exp) 
-  %%    \MID (\key{or}\;\Exp\;\Exp) 
-  %%    \MID (\key{not}\;\Exp) } \\
-  %%   &\MID& \gray{ (\key{eq?}\;\Exp\;\Exp) \MID \CIF{\Exp}{\Exp}{\Exp} } \\
-  %%   &\MID& \gray{ (\key{vector}\;\Exp\ldots) \MID
-  %%         (\key{vector-ref}\;\Exp\;\Int)} \\
-  %%   &\MID& \gray{(\key{vector-set!}\;\Exp\;\Int\;\Exp)\MID (\key{void})
-  %%   \MID (\Exp \; \Exp\ldots) } \\
-  %%   &\MID& \LP \key{procedure-arity}~\Exp\RP \\
-  %%   &\MID& \CLAMBDA{\LP\LS\Var \key{:} \Type\RS\ldots\RP}{\Type}{\Exp} \\
-  %% \Def &::=& \gray{ \CDEF{\Var}{\LS\Var \key{:} \Type\RS\ldots}{\Type}{\Exp} } \\
   \LangLamM{} &::=& \Def\ldots \; \Exp
   \end{array}
 \end{array}
@@ -14630,15 +14614,6 @@ syntax for function application.
   \gray{\LfunASTRacket} \\ \hline
   \LlambdaASTRacket \\
   \begin{array}{lcl}
- %%  \itm{op} &::=& \ldots \MID \code{procedure-arity} \\
- %%  \Exp &::=& \gray{ \INT{\Int} \VAR{\Var} \MID \LET{\Var}{\Exp}{\Exp} } \\
- %%       &\MID& \gray{ \PRIM{\itm{op}}{\Exp\ldots} }\\
- %%     &\MID& \gray{ \BOOL{\itm{bool}}
- %%      \MID \IF{\Exp}{\Exp}{\Exp} } \\
- %%     &\MID& \gray{ \VOID{} \MID \LP\key{HasType}~\Exp~\Type \RP 
- %%     \MID \APPLY{\Exp}{\Exp\ldots} }\\
- %%     &\MID& \LAMBDA{\LP\LS\Var\code{:}\Type\RS\ldots\RP}{\Type}{\Exp}\\
- %% \Def &::=& \gray{ \FUNDEF{\Var}{\LP\LS\Var \code{:} \Type\RS\ldots\RP}{\Type}{\code{'()}}{\Exp} }\\
   \LangLamM{} &::=& \gray{ \PROGRAMDEFSEXP{\code{'()}}{\LP\Def\ldots\RP}{\Exp} }
   \end{array}
 \end{array}
@@ -14725,12 +14700,13 @@ require the body's type to match the declared return type.
 \section{Assignment and Lexically Scoped Functions}
 \label{sec:assignment-scoping}
 
-The combination of lexically-scoped functions and assignment
-(i.e. \code{set!}) raises a challenge with our approach to
-implementing lexically-scoped functions. Consider the following
-example in which function \code{f} has a free variable \code{x} that
-is changed after \code{f} is created but before the call to \code{f}.
+The combination of lexically-scoped functions and assignment to
+variables raises a challenge with our approach to implementing
+lexically-scoped functions. Consider the following example in which
+function \code{f} has a free variable \code{x} that is changed after
+\code{f} is created but before the call to \code{f}.
 % loop_test_11.rkt
+{\if\edition\racketEd
 \begin{lstlisting}
 (let ([x 0])
   (let ([y 0])
@@ -14741,6 +14717,19 @@ is changed after \code{f} is created but before the call to \code{f}.
           (set! y 12)
           (f y))))))
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+%  assign_free.py
+\begin{lstlisting}
+    x = 0
+    y = 0  
+    z = 20
+    f : Callable[[int],int] = lambda a: a + x + z
+    x = 10
+    y = 12
+    print( f(y) )
+\end{lstlisting}
+\fi}
 The correct output for this example is \code{42} because the call to
 \code{f} is required to use the current value of \code{x} (which is
 \code{10}). Unfortunately, the closure conversion pass
@@ -14753,41 +14742,79 @@ A first attempt at solving this problem would be to save a pointer to
 \code{x} in the closure and change the occurrences of \code{x} inside
 the lambda to dereference the pointer. Of course, this would require
 assigning \code{x} to the stack and not to a register. However, the
-problem goes a bit deeper. Consider the following example in which we
-create a counter abstraction by creating a pair of functions that
-share the free variable \code{x}.
+problem goes a bit deeper.
+%% Consider the following example in which we
+%% create a counter abstraction by creating a pair of functions that
+%% share the free variable \code{x}.
+Consider the following example that returns a function that refers to
+a local variable of the enclosing function.
+\begin{center}
+\begin{minipage}{\textwidth}
+{\if\edition\racketEd
 % similar to loop_test_10.rkt
+%% \begin{lstlisting}
+%% (define (f [x : Integer]) : (Vector ( -> Integer) ( -> Void))
+%%   (vector
+%%    (lambda: () : Integer x)
+%%    (lambda: () : Void (set! x (+ 1 x)))))
+
+%% (let ([counter (f 0)])
+%%   (let ([get (vector-ref counter 0)])
+%%     (let ([inc (vector-ref counter 1)])
+%%       (begin
+%%         (inc)
+%%         (get)))))
+%% \end{lstlisting}
 \begin{lstlisting}
-(define (f [x : Integer]) : (Vector ( -> Integer) ( -> Void))
-  (vector
-   (lambda: () : Integer x)
-   (lambda: () : Void (set! x (+ 1 x)))))
-
-(let ([counter (f 0)])
-  (let ([get (vector-ref counter 0)])
-    (let ([inc (vector-ref counter 1)])
+(define (f []) : Integer
+  (let ([x 0])
+    (let ([g (lambda: () : Integer x)])
       (begin
-        (inc)
-        (get)))))
+        (set! x 42)
+        g))))
+((f))
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+% counter.py  
+\begin{lstlisting}
+def f():
+    x = 0
+    g = lambda: x
+    x = 42
+    return g
+
+print( f()() )
+\end{lstlisting}
+\fi}
+\end{minipage}
+\end{center}
 In this example, the lifetime of \code{x} extends beyond the lifetime
 of the call to \code{f}. Thus, if we were to store \code{x} on the
 stack frame for the call to \code{f}, it would be gone by the time we
-call \code{inc} and \code{get}, leaving us with dangling pointers for
+call \code{g}, leaving us with dangling pointers for
 \code{x}. This example demonstrates that when a variable occurs free
-inside a \code{lambda}, its lifetime becomes indefinite. Thus, the
-value of the variable needs to live on the heap.  The verb ``box'' is
-often used for allocating a single value on the heap, producing a
-pointer, and ``unbox'' for dereferencing the pointer.
-
-We recommend solving these problems by ``boxing'' the local variables
-that are in the intersection of 1) variables that appear on the
-left-hand-side of a \code{set!} and 2) variables that occur free
-inside a \code{lambda}. We shall introduce a new pass named
-\code{convert-assignments} in Section~\ref{sec:convert-assignments} to
-perform this translation. But before diving into the compiler passes,
-we one more problem to discuss.
+inside a function, its lifetime becomes indefinite. Thus, the value of
+the variable needs to live on the heap.  The verb
+\emph{box}\index{subject}{box} is often used for allocating a single
+value on the heap, producing a pointer, and
+\emph{unbox}\index{subject}{unbox} for dereferencing the pointer.
 
+{\if\edition\racketEd
+We recommend solving these problems by boxing the local variables that
+are in the intersection of 1) variables that appear on the
+left-hand-side of a \code{set!}  and 2) variables that occur free
+inside a \code{lambda}.
+\fi}
+{\if\edition\pythonEd
+We recommend solving these problems by boxing the local variables that
+are in the intersection of 1) variables whose values may change and 2)
+variables that occur free inside a \code{lambda}.
+\fi}
+We shall introduce a new pass named
+\code{convert\_assignments} in Section~\ref{sec:convert-assignments}
+to perform this translation. But before diving into the compiler
+passes, we one more problem to discuss.
 
 \section{Reveal Functions and the $F_2$ language}
 \label{sec:reveal-functions-r5}