|
@@ -16647,11 +16647,11 @@ for \LangFun{}, which already has syntax for function application.
|
|
%
|
|
%
|
|
\racket{The \code{procedure-arity} operation returns the number of parameters
|
|
\racket{The \code{procedure-arity} operation returns the number of parameters
|
|
of a given function, an operation that we need for the translation
|
|
of a given function, an operation that we need for the translation
|
|
- of dynamic typing in chapter~\ref{ch:Ldyn}.}
|
|
|
|
|
|
+ of dynamic typing that is discussed in chapter~\ref{ch:Ldyn}.}
|
|
%
|
|
%
|
|
\python{The \code{arity} operation returns the number of parameters of
|
|
\python{The \code{arity} operation returns the number of parameters of
|
|
a given function, an operation that we need for the translation
|
|
a given function, an operation that we need for the translation
|
|
- of dynamic typing in chapter~\ref{ch:Ldyn}.
|
|
|
|
|
|
+ of dynamic typing that is discussed in chapter~\ref{ch:Ldyn}.
|
|
The \code{arity} operation is not in Python, but the same functionality
|
|
The \code{arity} operation is not in Python, but the same functionality
|
|
is available in a more complex form. We include \code{arity} in the
|
|
is available in a more complex form. We include \code{arity} in the
|
|
\LangLam{} source language to enable testing.}
|
|
\LangLam{} source language to enable testing.}
|
|
@@ -16862,11 +16862,11 @@ Figures~\ref{fig:type-check-Llambda} and
|
|
\LangLam{}, which is more complex than one might expect. The reason
|
|
\LangLam{}, which is more complex than one might expect. The reason
|
|
for the added complexity is that the syntax of \key{lambda} does not
|
|
for the added complexity is that the syntax of \key{lambda} does not
|
|
include type annotations for the parameters or return type. Instead
|
|
include type annotations for the parameters or return type. Instead
|
|
-they must be inferred. There are many approaches of type inference to
|
|
|
|
-choose from of varying degrees of complexity. We choose one of the
|
|
|
|
-simpler approaches, bidirectional type inference~\citep{Dunfield:2021}
|
|
|
|
-(aka. local type inference~\citep{Pierce:2000}), because the focus of
|
|
|
|
-this book is compilation, not type inference.
|
|
|
|
|
|
+they must be inferred. There are many approaches to type inference
|
|
|
|
+from which to choose, of varying degrees of complexity. We choose one
|
|
|
|
+of the simpler approaches, bidirectional type
|
|
|
|
+inference~\citep{Pierce:2000,Dunfield:2021}, because the focus of this
|
|
|
|
+book is compilation, not type inference.
|
|
|
|
|
|
The main idea of bidirectional type inference is to add an auxiliary
|
|
The main idea of bidirectional type inference is to add an auxiliary
|
|
function, here named \code{check\_exp}, that takes an expected type
|
|
function, here named \code{check\_exp}, that takes an expected type
|
|
@@ -16878,14 +16878,14 @@ manner.
|
|
%
|
|
%
|
|
The idea then is to use \code{check\_exp} in all the places where we
|
|
The idea then is to use \code{check\_exp} in all the places where we
|
|
already know what the type of an expression should be, such as in the
|
|
already know what the type of an expression should be, such as in the
|
|
-\code{return} statement of a top-level function definition, or on the
|
|
|
|
|
|
+\code{return} statement of a top-level function definition or on the
|
|
right-hand side of an annotated assignment statement.
|
|
right-hand side of an annotated assignment statement.
|
|
|
|
|
|
-Getting back to \code{lambda}, it is straightforward to check a
|
|
|
|
|
|
+With regard to \code{lambda}, it is straightforward to check a
|
|
\code{lambda} inside \code{check\_exp} because the expected type
|
|
\code{lambda} inside \code{check\_exp} because the expected type
|
|
provides the parameter types and the return type. On the other hand,
|
|
provides the parameter types and the return type. On the other hand,
|
|
inside \code{type\_check\_exp} we disallow \code{lambda}, which means
|
|
inside \code{type\_check\_exp} we disallow \code{lambda}, which means
|
|
-that we do not allow \code{lambda} in contexts where we don't already
|
|
|
|
|
|
+that we do not allow \code{lambda} in contexts in which we don't already
|
|
know its type. This restriction does not incur a loss of
|
|
know its type. This restriction does not incur a loss of
|
|
expressiveness for \LangLam{} because it is straightforward to modify
|
|
expressiveness for \LangLam{} because it is straightforward to modify
|
|
a program to sidestep the restriction, for example, by using an
|
|
a program to sidestep the restriction, for example, by using an
|
|
@@ -16894,7 +16894,7 @@ temporary variable.
|
|
|
|
|
|
Note that for the \code{Name} and \code{Lambda} AST nodes, the type
|
|
Note that for the \code{Name} and \code{Lambda} AST nodes, the type
|
|
checker records their type in a \code{has\_type} field. This type
|
|
checker records their type in a \code{has\_type} field. This type
|
|
-information is used later in this chapter.
|
|
|
|
|
|
+information is used further on in this chapter.
|
|
%
|
|
%
|
|
\fi}
|
|
\fi}
|
|
|
|
|
|
@@ -17143,15 +17143,14 @@ print(f(0, 10)(32))
|
|
\end{lstlisting}
|
|
\end{lstlisting}
|
|
|
|
|
|
Many of our compiler passes rely on being able to connect variable
|
|
Many of our compiler passes rely on being able to connect variable
|
|
-uses with their definitions using just the name of the variable,
|
|
|
|
-including new passes in this chapter. However, in the above example
|
|
|
|
-the name of the variable does not uniquely determine its
|
|
|
|
-definition. To solve this problem we recommend implementing a pass
|
|
|
|
-named \code{uniquify} that renames every variable in the program to
|
|
|
|
-make sure they are all unique.
|
|
|
|
-
|
|
|
|
-The following shows the result of \code{uniquify} for the above
|
|
|
|
-example. The \code{x} parameter of \code{f} is renamed to \code{x\_0}
|
|
|
|
|
|
+uses with their definitions using just the name of the
|
|
|
|
+variable. However, in the example above the name of the variable does
|
|
|
|
+not uniquely determine its definition. To solve this problem we
|
|
|
|
+recommend implementing a pass named \code{uniquify} that renames every
|
|
|
|
+variable in the program to make sure that they are all unique.
|
|
|
|
+
|
|
|
|
+The following shows the result of \code{uniquify} for the example
|
|
|
|
+above. The \code{x} parameter of \code{f} is renamed to \code{x\_0},
|
|
and the \code{x} parameter of the \code{lambda} is renamed to
|
|
and the \code{x} parameter of the \code{lambda} is renamed to
|
|
\code{x\_4}.
|
|
\code{x\_4}.
|
|
|
|
|
|
@@ -17302,7 +17301,7 @@ as \code{Lambda}.
|
|
To compute the variables that are assigned to, we recommend defining
|
|
To compute the variables that are assigned to, we recommend defining
|
|
an auxiliary function named \code{assigned\_vars\_stmt} that returns
|
|
an auxiliary function named \code{assigned\_vars\_stmt} that returns
|
|
the set of variables that occur in the left-hand side of an assignment
|
|
the set of variables that occur in the left-hand side of an assignment
|
|
-statement, and otherwise returns the empty set.
|
|
|
|
|
|
+statement and otherwise returns the empty set.
|
|
%
|
|
%
|
|
\fi}
|
|
\fi}
|
|
|
|
|
|
@@ -17783,7 +17782,7 @@ extract the $5$ bits starting at position $58$ from the tag.}
|
|
%
|
|
%
|
|
\python{Compile a call to the \code{arity} operator to a sequence of
|
|
\python{Compile a call to the \code{arity} operator to a sequence of
|
|
instructions that access the tag from position $0$ of the tuple
|
|
instructions that access the tag from position $0$ of the tuple
|
|
-(representing a closure) and extract the $5$-bits starting at position
|
|
|
|
|
|
+(representing a closure) and extract the $5$ bits starting at position
|
|
$58$ from the tag.}
|
|
$58$ from the tag.}
|
|
|
|
|
|
|
|
|
|
@@ -18118,7 +18117,7 @@ direct call when the operator is a variable and \racket{the variable
|
|
the variable is a closure}. This can be accomplished by maintaining
|
|
the variable is a closure}. This can be accomplished by maintaining
|
|
an environment that maps variables to function names. Extend the
|
|
an environment that maps variables to function names. Extend the
|
|
environment whenever you encounter a closure on the right-hand side of
|
|
environment whenever you encounter a closure on the right-hand side of
|
|
-a \racket{\code{let}}\python{assignment}, mapping the variable to the
|
|
|
|
|
|
+\racket{a \code{let}}\python{an assignment}, mapping the variable to the
|
|
name of the global function for the closure. This pass should come
|
|
name of the global function for the closure. This pass should come
|
|
after closure conversion.
|
|
after closure conversion.
|
|
|
|
|