|
@@ -3027,15 +3027,17 @@ use of a variable, it can lookup its type in the association list.
|
|
|
\label{fig:type-check-R2}
|
|
|
\end{figure}
|
|
|
|
|
|
-In order to print the resulting value correctly, the overall type of the program
|
|
|
-has to be threaded through the remainder of the passes. We can store the type
|
|
|
-within the \key{program} form as a new node. This is shown in Figure \ref{fig:type-check-R2}. The syntax for post-typechecking $R_2$ programs is below:
|
|
|
+To print the resulting value correctly, the overall type of the
|
|
|
+program must be threaded through the remainder of the passes. We can
|
|
|
+store the type within the \key{program} form as shown in Figure
|
|
|
+\ref{fig:type-check-R2}. The syntax for post-typechecking $R_2$
|
|
|
+programs is below:
|
|
|
|
|
|
\fbox{
|
|
|
\begin{minipage}{0.96\textwidth}
|
|
|
\[
|
|
|
\begin{array}{lcl}
|
|
|
- R_2 &::=& (\key{program}\;(\key{type}\;\textt{type})\; \Exp)
|
|
|
+ R_2 &::=& (\key{program}\;(\key{type}\;\textit{type})\; \Exp)
|
|
|
\end{array}
|
|
|
\]
|
|
|
\end{minipage}
|
|
@@ -4949,6 +4951,48 @@ programs.
|
|
|
\chapter{Lexically Scoped Functions}
|
|
|
\label{ch:lambdas}
|
|
|
|
|
|
+This chapter studies lexically scoped functions as they appear in
|
|
|
+functional languages such as Racket. By lexical scoping we mean that a
|
|
|
+function's body may refer to variables whose binding site is outside
|
|
|
+of the function, in an enclosing scope. Consider the example in
|
|
|
+Figure~\ref{fig:lexical-scoping} featuring an anonymous function
|
|
|
+defined using the \key{lambda} form.
|
|
|
+
|
|
|
+\begin{figure}[btp]
|
|
|
+\begin{lstlisting}
|
|
|
+ (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}
|
|
|
+\caption{Example of a lexically scoped function.}
|
|
|
+\label{fig:lexical-scoping}
|
|
|
+\end{figure}
|
|
|
+
|
|
|
+The body of the \key{lambda}, \code{(+ x (+ y z))}, refers to three
|
|
|
+variables. The binding sites for \code{x} and \code{y} are outside of
|
|
|
+the \key{lambda}: \code{y} is bound by the enclosing \key{let} and
|
|
|
+\code{x} is a parameter of \code{f}. The \key{lambda} is returned from
|
|
|
+the function \code{f}. Below the definition of \code{f}, we have two
|
|
|
+calls to \code{f} with different arguments for \code{x}, first
|
|
|
+\code{5} then \code{3}. The functions returned from \code{f} are bound
|
|
|
+to \code{g} and \code{h}. Even though these two functions were created
|
|
|
+by the same \code{lambda}, they are really different functions because
|
|
|
+they use different values for \code{x}. Finally, we apply \code{g} to
|
|
|
+\code{11} (producing \code{20}) and apply \code{h} to \code{15}
|
|
|
+(producing \code{22}) so the result of this program is \code{42}.
|
|
|
+
|
|
|
+The syntax for this language with lexical scoping, $R_5$, is defined
|
|
|
+in Figure~\ref{fig:r5-syntax}. It adds the \key{lambda} form to the
|
|
|
+grammar for $R_4$, which already has syntax for function application.
|
|
|
+In this chapter we shall descibe how to compile $R_5$ back into $R_4$,
|
|
|
+compiling lexically-scoped functions into a combination of functions
|
|
|
+(as in $R_4$) and tuples (as in $R_3$).
|
|
|
+
|
|
|
\begin{figure}[tbp]
|
|
|
\centering
|
|
|
\fbox{
|
|
@@ -4966,6 +5010,38 @@ programs.
|
|
|
\label{fig:r5-syntax}
|
|
|
\end{figure}
|
|
|
|
|
|
+Our compiler must provide special treatment to variable occurences
|
|
|
+such as \code{x} and \code{y} in the body of the \code{lambda} of
|
|
|
+Figure~\ref{fig:lexical-scoping}, for the functions of $R_4$ may not
|
|
|
+refer to variables defined outside the function. To identify such
|
|
|
+variable occurences, we review the standard notion of free variable.
|
|
|
+
|
|
|
+\begin{definition}
|
|
|
+A variable is \textbf{\emph{free with respect to an expression}} $e$
|
|
|
+if the variable occurs inside $e$ but does not have an enclosing
|
|
|
+binding in $e$.
|
|
|
+\end{definition}
|
|
|
+
|
|
|
+For example, the variables \code{x}, \code{y}, and \code{z} are all
|
|
|
+free with respect to the expression \code{(+ x (+ y z))}. On the
|
|
|
+other hand, only \code{x} and \code{y} are free with respect to the
|
|
|
+following expression becuase \code{z} is bound by the \code{lambda}.
|
|
|
+\begin{lstlisting}
|
|
|
+ (lambda ([z : Integer]) : Integer
|
|
|
+ (+ x (+ y z)))
|
|
|
+\end{lstlisting}
|
|
|
+
|
|
|
+Once we have identified the free variables of a \code{lamda}, we need
|
|
|
+to arrange for some way to transport, at runtime, the values of those
|
|
|
+variables from the point where the \code{lambda} was created to the
|
|
|
+point where the \code{lambda} is applied. Referring again to
|
|
|
+Figure~\ref{fig:lexical-scoping}, the binding of \code{x} to \code{5}
|
|
|
+needs to be used in the application of \code{g} to \code{11}, but the
|
|
|
+binding of \code{x} to \code{3} needs to be used in the application of
|
|
|
+\code{h} to \code{15}.
|
|
|
+
|
|
|
+UNDER CONSTRUCTION
|
|
|
+
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
%\chapter{Mutable Data}
|