Sfoglia il codice sorgente

updates to chapter 8

Jeremy Siek 4 anni fa
parent
commit
187a685e2b
1 ha cambiato i file con 99 aggiunte e 103 eliminazioni
  1. 99 103
      book.tex

+ 99 - 103
book.tex

@@ -8267,50 +8267,46 @@ an extra closure parameter.
 \section{An Example Translation}
 \label{sec:example-lambda}
 
-Figure~\ref{fig:lexical-functions-example} shows the result of closure
-conversion for the example program demonstrating lexical scoping that
-we discussed at the beginning of this chapter.
+Figure~\ref{fig:lexical-functions-example} shows the result of
+\code{reveal-functions} and then \code{convert-to-closures} for the
+example program demonstrating lexical scoping that we discussed at the
+beginning of this chapter.
 
 
 \begin{figure}[h]
-\begin{minipage}{0.8\textwidth}
+  \begin{minipage}{0.8\textwidth}
+% tests/s4_6.rkt
 \begin{lstlisting}%[basicstyle=\ttfamily\footnotesize]
-(program
- (define (f [x : Integer]) : (Integer -> Integer)
-    (let ([y 4])
-       (lambda: ([z : Integer]) : Integer
-          (+ x (+ y z)))))
- (let ([g (f 5)])
-   (let ([h (f 3)])
-     (+ (g 11) (h 15)))))
-\end{lstlisting}
-$\Downarrow$
-\begin{lstlisting}%[basicstyle=\ttfamily\footnotesize]
-(program (type Integer)
-  (define (f (x : Integer)) : (Integer -> Integer)
-    (let ((y 4))
-       (lambda: ((z : Integer)) : Integer
-         (+ x (+ y z)))))
-   (let ((g (app (fun-ref f) 5)))
-      (let ((h (app (fun-ref f) 3)))
-         (+ (app g 11) (app h 15)))))
+(define (f74  [x75 : Integer]) : (Integer -> Integer)
+   (let ([y76 4])
+      (lambda: ( [z77 : Integer]) : Integer
+         (+ x75 (+ y76 z77)))))
+
+(define (main) : Integer
+   (let ([g78 ((fun-ref f74) 5)])
+      (let ([h79 ((fun-ref f74) 3)])
+         (+ (g78 11) (h79 15)))))
 \end{lstlisting}
 $\Downarrow$
 \begin{lstlisting}%[basicstyle=\ttfamily\footnotesize]
-(program (type Integer)
-  (define (f (clos.1 : _) (x : Integer)) : (Integer -> Integer)
-     (let ((y 4))
-        (vector (fun-ref lam.1) x y)))
-  (define (lam.1 (clos.2 : _) (z : Integer)) : Integer
-     (let ((x (vector-ref clos.2 1)))
-        (let ((y (vector-ref clos.2 2)))
-           (+ x (+ y z)))))
-   (let ((g (let ((t.1 (vector (fun-ref f))))
-              (app (vector-ref t.1 0) t.1 5))))
-      (let ((h (let ((t.2 (vector  (fun-ref f))))
-                 (app (vector-ref t.2 0) t.2 3))))
-         (+ (let ((t.3 g)) (app (vector-ref t.3 0) t.3 11))
-            (let ((t.4 h)) (app (vector-ref t.4 0) t.4 15))))))
+(define (f74  [fvs82 : _] [x75 : Integer]) : (Vector ((Vector _) Integer -> Integer))
+   (let ([y76 4])
+      (vector (fun-ref lambda80) x75 y76)))
+
+(define (lambda80  [fvs81 : (Vector _ Integer Integer)] [z77 : Integer]) : Integer
+   (let ([x75 (vector-ref fvs81 1)])
+      (let ([y76 (vector-ref fvs81 2)])
+         (+ x75 (+ y76 z77)))))
+
+(define (main) : Integer
+   (let ([g78 (let ([app83 (vector (fun-ref f74))])
+                    ((vector-ref app83 0) app83 5))])
+      (let ([h79 (let ([app84 (vector (fun-ref f74))])
+                       ((vector-ref app84 0) app84 3))])
+         (+ (let ([app85 g78])
+               ((vector-ref app85 0) app85 11))
+             (let ([app86 h79])
+                ((vector-ref app86 0) app86 15))))))
 \end{lstlisting}
 \end{minipage}
 
@@ -8392,23 +8388,24 @@ your previously created test programs.
 \label{ch:type-dynamic}
 \index{dynamic typing}
 
-In this chapter we discuss the compilation of a dynamically typed
-language, named $R_7$, that is a subset of the Racket
-language. (Recall that in the previous chapters we have studied
-subsets of the \emph{Typed} Racket language.) In dynamically typed
-languages, an expression may produce values of differing
-type. Consider the following example with a conditional expression
-that may return a Boolean or an integer depending on the input to the
-program.
+In this chapter we discuss the compilation $R_7$, a dynamically typed
+language and a subset of the Racket language. Recall that in the
+previous chapters we have compiled subsets of the \emph{Typed} Racket
+language. In dynamically typed languages, each evaluation of an
+expression may produce a value of a different type. Consider the
+following example with a conditional expression that may return a
+Boolean or an integer depending on the input to the program.
 \begin{lstlisting}
    (not (if (eq? (read) 1) #f 0))
 \end{lstlisting}
 Languages that allow expressions to produce different kinds of values
-are called \emph{polymorphic}. There are many kinds of polymorphism,
-such as subtype polymorphism and parametric
-polymorphism~\citep{Cardelli:1985kx}. The kind of polymorphism we are
-talking about here does not have a special name, but it is the usual
-kind that arises in dynamically typed languages.
+are called \emph{polymorphic}, a word composed of the Greek roots
+``poly'', meaning ``many'', and ``morph'', meaning ``shape''.  There
+are several kinds of polymorphism in programming languages, such as
+subtype polymorphism and parametric
+polymorphism~\citep{Cardelli:1985kx}. The kind of polymorphism we
+study in this chapter does not have a special name but it is the kind
+that arises in dynamically typed languages.
 
 Another characteristic of dynamically typed languages is that
 primitive operations, such as \code{not}, are often defined to operate
@@ -8418,7 +8415,8 @@ returns \code{\#t} and given anything else it returns \code{\#f}.
 Furthermore, even when primitive operations restrict their inputs to
 values of a certain type, this restriction is enforced at runtime
 instead of during compilation. For example, the following vector
-reference results in a run-time contract violation.
+reference results in a run-time contract violation because the index
+must be in integer, not a Boolean such as \code{\#t}.
 \begin{lstlisting}
    (vector-ref (vector 42) #t)
 \end{lstlisting}
@@ -8457,64 +8455,62 @@ R_7  &::=& (\key{program} \; \Def\ldots\; \Exp)
 The syntax of $R_7$, our subset of Racket, is defined in
 Figure~\ref{fig:r7-syntax}.
 %
-The definitional interpreter for $R_7$ is given in
+There is no type checker for $R_7$ because it is not a statically
+typed language (it's dynamically typed!).
+%
+The definitional interpreter for $R_7$ is presented in
 Figure~\ref{fig:interp-R7}.
 
 \begin{figure}[tbp]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
-(define (get-tagged-type v) (match v [`(tagged ,v1 ,ty) ty]))
-
-(define (valid-op? op) (member op '(+ - and or not)))
-
-(define (interp-r7 env)
+(define (interp-R7-exp env)
   (lambda (ast)
-    (define recur (interp-r7 env))
+    (define recur (interp-R7-exp env))
     (match ast
-      [(? symbol?) (lookup ast env)]
-      [(? integer?) `(inject ,ast Integer)]
-      [#t `(inject #t Boolean)]
-      [#f `(inject #f Boolean)]
-      [`(read) `(inject ,(read-fixnum) Integer)]
-      [`(lambda (,xs ...) ,body)
-       `(inject (lambda ,xs ,body ,env) (,@(map (lambda (x) 'Any) xs) -> Any))]
-      [`(define (,f ,xs ...) ,body)
-       (mcons f `(lambda ,xs ,body))]
-      [`(program ,ds ... ,body)
-       (let ([top-level (for/list ([d ds]) ((interp-r7 '()) d))])
-         (for/list ([b top-level])
-           (set-mcdr! b (match (mcdr b)
-                          [`(lambda ,xs ,body)
-                           `(inject (lambda ,xs ,body ,top-level)
-                                    (,@(map (lambda (x) 'Any) xs) -> Any))])))
-         ((interp-r7 top-level) body))]
-      [`(vector ,(app recur elts) ...)
-       (define tys (map get-tagged-type elts))
-       `(inject ,(apply vector elts) (Vector ,@tys))]
-      [`(vector-set! ,(app recur v1) ,n ,(app recur v2))
-         (match v1
-           [`(inject ,vec ,ty)
-             (vector-set! vec n v2)
-            `(inject (void) Void)])]
-      [`(vector-ref ,(app recur v) ,n)
-       (match v [`(inject ,vec ,ty) (vector-ref vec n)])]
-      [`(let ([,x ,(app recur v)]) ,body)
-       ((interp-r7 (cons (cons x v) env)) body)]
-      [`(,op ,es ...) #:when (valid-op? op)
-       (interp-r7-op op (for/list ([e es]) (recur e)))]
-      [`(eq? ,(app recur l) ,(app recur r))
-       `(inject ,(equal? l r) Boolean)]
-      [`(if ,(app recur q) ,t ,f)
-       (match q
-         [`(inject #f Boolean) (recur f)]
-         [else (recur t)])]
-      [`(,(app recur f-val) ,(app recur vs) ...)
-       (match f-val
-         [`(inject (lambda (,xs ...) ,body ,lam-env) ,ty)
-          (define new-env (append (map cons xs vs) lam-env))
-          ((interp-r7 new-env) body)]
-         [else (error "interp-r7, expected function, not" f-val)])])))
-\end{lstlisting}
-\caption{Interpreter for the $R_7$ language. UPDATE ME -Jeremy}
+      [(Var x) (lookup x env)]
+      [(Int n) `(tagged ,n Integer)]
+      [(Bool b) `(tagged ,b Boolean)]
+      [(Prim 'read '()) `(tagged ,(read-fixnum) Integer)]
+      [(Lambda xs rt body)
+       `(tagged (lambda ,xs ,body ,env) (,@(for/list ([x xs]) 'Any) -> Any))]
+      [(Prim 'vector es)
+       `(tagged ,(apply vector (for/list ([e es]) (recur e)))
+                (Vector ,@(for/list ([e es]) 'Any)))]
+      [(Prim 'vector-set! (list e1 n e2))
+       (define vec (value-of-any (recur e1)))
+       (define i (value-of-any (recur n)))
+       (vector-set! vec i (recur e2))
+       `(tagged ,(void) Void)]
+      [(Prim 'vector-ref (list e1 n))
+       (define vec (value-of-any (recur e1)))
+       (define i (value-of-any (recur n)))
+       (vector-ref vec i)]
+      [(Let x e body)
+       (define v (recur e))
+       ((interp-R7-exp (cons (cons x v) env)) body)]
+      [(Prim 'and (list e1 e2))
+       (recur (If e1 e2 (Bool #f)))]
+      [(Prim 'or (list e1 e2))
+       (define v1 (recur e1))
+       (match (value-of-any v1) [#f (recur e2)] [else v1])]
+      [(Prim 'eq? (list l r))
+       `(tagged ,(equal? (recur l) (recur r)) Boolean)]
+      [(If q t f)
+       (match (value-of-any (recur q)) [#f (recur f)] [else (recur t)])]
+      [(Prim op es)
+       (tag-value
+        (apply (interp-op op) (for/list ([e es]) (value-of-any (recur e)))))]
+      [(Apply f es)
+       (define new-args (map recur es))
+       (let ([f-val (value-of-any (recur f))])
+         (match f-val 
+           [`(lambda (,xs ...) ,body ,lam-env)
+            (define new-env (append (map cons xs new-args) lam-env))
+            ((interp-R7-exp new-env) body)]
+           [else (error "interp-R7-exp, expected function, not" f-val)]))]
+      )))
+\end{lstlisting}
+\caption{Interpreter for the $R_7$ language.}
 \label{fig:interp-R7}
 \end{figure}