|
@@ -279,7 +279,7 @@ a compiler extension of their choosing. The later chapters can be
|
|
|
used in support of these projects. For compiler courses at
|
|
|
universities on the quarter system (about 10 weeks in length), we
|
|
|
recommend completing up through Chapter~\ref{ch:Lvec} or
|
|
|
-Chapter~\ref{ch:Lfun} and providing some scafolding code to the
|
|
|
+Chapter~\ref{ch:Lfun} and providing some scaffolding code to the
|
|
|
students for each compiler pass.
|
|
|
%
|
|
|
The course can be adapted to emphasize functional languages by
|
|
@@ -1853,7 +1853,7 @@ result?
|
|
|
\begin{lstlisting}
|
|
|
(let ([x 32]) (+ (let ([x 10]) x) x))
|
|
|
\end{lstlisting}
|
|
|
-For the purposes of depicting which variable occurences correspond to
|
|
|
+For the purposes of depicting which variable occurrences correspond to
|
|
|
which definitions, the following shows the \code{x}'s annotated with
|
|
|
subscripts to distinguish them. Double check that your answer for the
|
|
|
above is the same as your answer for this annotated version of the
|
|
@@ -2802,9 +2802,9 @@ dead end in \key{assign\_homes}. Recall that only one argument of an
|
|
|
x86 instruction may be a memory access but \key{assign\_homes} might
|
|
|
be forced to assign both arguments to memory locations.
|
|
|
%
|
|
|
-A sophisticated approach is to iteratively repeat the two passes until
|
|
|
-a solution is found. However, to reduce implementation complexity we
|
|
|
-recommend placing \key{select\_instructions} first, followed by the
|
|
|
+A sophisticated approach is to repeat the two passes until a solution
|
|
|
+is found. However, to reduce implementation complexity we recommend
|
|
|
+placing \key{select\_instructions} first, followed by the
|
|
|
\key{assign\_homes}, then a third pass named \key{patch\_instructions}
|
|
|
that uses a reserved register to fix outstanding problems.
|
|
|
|
|
@@ -3210,7 +3210,7 @@ in the name \LangVarANF{}. An important invariant of the
|
|
|
\code{remove\_complex\_operands} pass is that the relative ordering
|
|
|
among complex expressions is not changed, but the relative ordering
|
|
|
between atomic expressions and complex expressions can change and
|
|
|
-often does. The reason that these changes are behaviour preserving is
|
|
|
+often does. The reason that these changes are behavior preserving is
|
|
|
that the atomic expressions are pure.
|
|
|
|
|
|
Another well-known form for intermediate languages is the
|
|
@@ -7301,7 +7301,7 @@ $C$ language~\citep{Kernighan:1988nx} in that it has labels and
|
|
|
The \LangCIf{} language supports the same operators as \LangIf{} but
|
|
|
the arguments of operators are restricted to atomic expressions. The
|
|
|
\LangCIf{} language does not include \code{if} expressions but it does
|
|
|
-include a restricted form of \code{if} statment. The condition must be
|
|
|
+include a restricted form of \code{if} statement. The condition must be
|
|
|
a comparison and the two branches may only contain \code{goto}
|
|
|
statements. These restrictions make it easier to translate \code{if}
|
|
|
statements to x86. The \LangCIf{} language also adds a \code{return}
|
|
@@ -7659,7 +7659,7 @@ this point).
|
|
|
\begin{lstlisting}
|
|
|
(list "shrink" shrink interp_Lif type-check-Lif)
|
|
|
\end{lstlisting}
|
|
|
-This instructs \code{interp-tests} to run the intepreter
|
|
|
+This instructs \code{interp-tests} to run the interpreter
|
|
|
\code{interp\_Lif} and the type checker \code{type-check-Lif} on the
|
|
|
output of \code{shrink}.
|
|
|
\fi}
|
|
@@ -7893,7 +7893,7 @@ the following code.
|
|
|
{\if\edition\pythonEd
|
|
|
\begin{lstlisting}
|
|
|
x = input_int()
|
|
|
-y = intput_int()
|
|
|
+y = input_int()
|
|
|
print(((y + 2) if x == 0 else (y + 10)) \
|
|
|
if (x < 1) \
|
|
|
else ((y + 2) if (x == 2) else (y + 10)))
|
|
@@ -8530,7 +8530,7 @@ which correspond to the two branches of the outer \key{if}, i.e.,
|
|
|
%
|
|
|
The story for \code{block\_5} is similar to that of \code{block\_4}.
|
|
|
%
|
|
|
-\python{The \code{block\_1} corresponds to the \code{print} statment
|
|
|
+\python{The \code{block\_1} corresponds to the \code{print} statement
|
|
|
at the end of the program.}
|
|
|
|
|
|
|
|
@@ -8745,7 +8745,7 @@ basic block has no successors (i.e. contains no jumps to other
|
|
|
blocks), then it has an empty live-after set and we can immediately
|
|
|
apply liveness analysis to it. If a basic block has some successors,
|
|
|
then we need to complete liveness analysis on those blocks
|
|
|
-first. These ordering contraints are the reverse of a
|
|
|
+first. These ordering constraints are the reverse of a
|
|
|
\emph{topological order}\index{subject}{topological order} on a graph
|
|
|
representation of the program. In particular, the \emph{control flow
|
|
|
graph} (CFG)\index{subject}{control-flow graph}~\citep{Allen:1970uq}
|
|
@@ -8908,9 +8908,9 @@ Add the following entry to the list of \code{passes} in
|
|
|
\label{sec:prelude-conclusion-cond}
|
|
|
|
|
|
The generation of the \code{main} function with its prelude and
|
|
|
-conclusion must change to accomodate how the program now consists of
|
|
|
+conclusion must change to accommodate how the program now consists of
|
|
|
one or more basic blocks. After the prelude in \code{main}, jump to
|
|
|
-the \code{start} block. Place the conclusion in a basic block labelled
|
|
|
+the \code{start} block. Place the conclusion in a basic block labeled
|
|
|
with \code{conclusion}.
|
|
|
|
|
|
\fi}
|
|
@@ -9255,7 +9255,7 @@ We use promises for the input and output of the functions
|
|
|
\racket{ and \code{explicate\_tail}}\python{ \code{explicate\_effect}, and \code{explicate\_stmt}}.
|
|
|
%
|
|
|
So instead of taking and returning \racket{$\Tail$
|
|
|
- expressions}\python{lists of statments}, they take and return
|
|
|
+ expressions}\python{lists of statements}, they take and return
|
|
|
promises. Furthermore, when we come to a situation in which a
|
|
|
continuation might be used more than once, as in the case for
|
|
|
\code{if} in \code{explicate\_pred}, we create a delayed computation
|
|
@@ -9632,7 +9632,7 @@ blocks on several test programs.
|
|
|
\label{sec:cond-further-reading}
|
|
|
|
|
|
The algorithm for the \code{explicate\_control} pass is based on the
|
|
|
-\code{explose-basic-blocks} pass in the course notes of
|
|
|
+\code{expose-basic-blocks} pass in the course notes of
|
|
|
\citet{Dybvig:2010aa}.
|
|
|
%
|
|
|
It has similarities to the algorithms of \citet{Danvy:2003fk} and
|
|
@@ -9847,7 +9847,7 @@ Section~\ref{sec:assignment-scoping}), we box the value that is bound
|
|
|
to each variable (in \code{Let}). The case for \code{Var} unboxes the
|
|
|
value.
|
|
|
%
|
|
|
-Now to discuss the new cases. For \code{SetBang}, we lookup the
|
|
|
+Now to discuss the new cases. For \code{SetBang}, we find the
|
|
|
variable in the environment to obtain a boxed value and then we change
|
|
|
it using \code{set-box!} to the result of evaluating the right-hand
|
|
|
side. The result value of a \code{SetBang} is \code{\#<void>}.
|
|
@@ -10356,7 +10356,7 @@ following variation that also involves a variable that is not mutated.
|
|
|
\end{lstlisting}
|
|
|
We first analyze the above program to discover that variable \code{x}
|
|
|
is mutable but \code{y} is not. We then transform the program as
|
|
|
-follows, replacing each occurence of \code{x} with \code{(get! x)}.
|
|
|
+follows, replacing each occurrence of \code{x} with \code{(get! x)}.
|
|
|
\begin{lstlisting}
|
|
|
(let ([x 2])
|
|
|
(let ([y 0])
|
|
@@ -10380,7 +10380,7 @@ program.\\
|
|
|
The temporary variable \code{t1} gets the value of \code{x} before the
|
|
|
\code{set!}, so it is \code{2}. The temporary variable \code{t2} gets
|
|
|
the value of \code{x} after the \code{set!}, so it is \code{40}. We
|
|
|
-do not generate a temporary variable for the occurence of \code{y}
|
|
|
+do not generate a temporary variable for the occurrence of \code{y}
|
|
|
because it's an immutable variable. We want to avoid such unnecessary
|
|
|
extra temporaries because they would needless increase the number of
|
|
|
variables, making it more likely for some of them to be spilled. The
|
|
@@ -10421,10 +10421,10 @@ The goal of this pass it to mark uses of mutable variables so that
|
|
|
\code{remove\_complex\_operands} can treat them as complex expressions
|
|
|
and thereby preserve their ordering relative to the side-effects in
|
|
|
other operands. So the first step is to collect all the mutable
|
|
|
-variables. We recommend creating an auxilliary function for this,
|
|
|
+variables. We recommend creating an auxiliary function for this,
|
|
|
named \code{collect-set!}, that recursively traverses expressions,
|
|
|
returning the set of all variables that occur on the left-hand side of a
|
|
|
-\code{set!}. Here's an exerpt of its implementation.
|
|
|
+\code{set!}. Here's an excerpt of its implementation.
|
|
|
\begin{center}
|
|
|
\begin{minipage}{\textwidth}
|
|
|
\begin{lstlisting}
|
|
@@ -10442,12 +10442,12 @@ returning the set of all variables that occur on the left-hand side of a
|
|
|
\end{center}
|
|
|
By placing this pass after \code{uniquify}, we need not worry about
|
|
|
variable shadowing and our logic for \code{Let} can remain simple, as
|
|
|
-in the exerpt above.
|
|
|
+in the excerpt above.
|
|
|
|
|
|
-The second step is to mark the occurences of the mutable variables
|
|
|
+The second step is to mark the occurrences of the mutable variables
|
|
|
with the new \code{GetBang} AST node (\code{get!} in concrete
|
|
|
-syntax). The following is an exerpt of the \code{uncover-get!-exp}
|
|
|
-function, which takes two parameters: the set of mutable varaibles
|
|
|
+syntax). The following is an excerpt of the \code{uncover-get!-exp}
|
|
|
+function, which takes two parameters: the set of mutable variables
|
|
|
\code{set!-vars}, and the expression \code{e} to be processed. The
|
|
|
case for \code{(Var x)} replaces it with \code{(GetBang x)} if it is a
|
|
|
mutable variable or leaves it alone if not.
|
|
@@ -10468,7 +10468,7 @@ mutable variable or leaves it alone if not.
|
|
|
To wrap things up, define the \code{uncover-get!} function for
|
|
|
processing a whole program, using \code{collect-set!} to obtain the
|
|
|
set of mutable variables and then \code{uncover-get!-exp} to replace
|
|
|
-their occurences with \code{GetBang}.
|
|
|
+their occurrences with \code{GetBang}.
|
|
|
|
|
|
|
|
|
\fi}
|
|
@@ -11333,7 +11333,7 @@ are using the term here.}
|
|
|
%
|
|
|
Unfortunately, it is impossible to know precisely which objects will
|
|
|
be accessed in the future and which will not. Instead, garbage
|
|
|
-collectors overapproximate the set of objects that will be accessed by
|
|
|
+collectors over approximate the set of objects that will be accessed by
|
|
|
identifying which objects can possibly be accessed. The running
|
|
|
program can directly access objects that are in registers and on the
|
|
|
procedure call stack. It can also transitively access the elements of
|
|
@@ -11453,7 +11453,7 @@ tuple whose second element is $42$ to the back of the queue. The other
|
|
|
pointer goes to a tuple that has already been copied, so we do not
|
|
|
need to copy it again, but we do need to update the pointer to the new
|
|
|
location. This can be accomplished by storing a \emph{forwarding
|
|
|
-pointer}\index{subect}{forwarding pointer} to the new location in the
|
|
|
+pointer}\index{subject}{forwarding pointer} to the new location in the
|
|
|
old tuple, back when we initially copied the tuple into the
|
|
|
ToSpace. This completes one step of the algorithm. The algorithm
|
|
|
continues in this way until the queue is empty, that is, when the scan
|
|
@@ -12424,7 +12424,7 @@ on the root stack to make room for the spills of tuple-typed
|
|
|
variables. We do so by bumping the root stack pointer (\code{r15})
|
|
|
taking care that the root stack grows up instead of down. For the
|
|
|
running example, there was just one spill so we increment \code{r15}
|
|
|
-by 8 bytes. In the conclusion we decrement \code{r15} by 8 bytes.
|
|
|
+by 8 bytes. In the conclusion we subtract 8 bytes from \code{r15}.
|
|
|
|
|
|
One issue that deserves special care is that there may be a call to
|
|
|
\code{collect} prior to the initializing assignments for all the
|
|
@@ -12637,7 +12637,7 @@ mark. The following example uses \code{set-point-x!} to change the
|
|
|
\section{Challenge: Arrays}
|
|
|
\label{sec:arrays}
|
|
|
|
|
|
-In Chapter~\ref{ch:Lvec} we studied tuples, that is, a heterogeous
|
|
|
+In Chapter~\ref{ch:Lvec} we studied tuples, that is, a heterogeneous
|
|
|
sequences of elements whose length is determined at compile-time. This
|
|
|
challenge is also about sequences, but this time the length is
|
|
|
determined at run-time and all the elements have the same type (they
|
|
@@ -12728,7 +12728,7 @@ UNDER CONSTRUCTION
|
|
|
The type checker for \LangArray{} is defined in
|
|
|
Figure~\ref{fig:type-check-Lvecof}. The result type of
|
|
|
\code{make-vector} is \code{(Vectorof T)} where \code{T} is the type
|
|
|
-of the intializing expression. The length expression is required to
|
|
|
+of the initializing expression. The length expression is required to
|
|
|
have type \code{Integer}. The type checking of the operators
|
|
|
\code{vector-length}, \code{vector-ref}, and \code{vector-set!} is
|
|
|
updated to handle the situation where the vector has type
|
|
@@ -13065,23 +13065,22 @@ present these findings.
|
|
|
\label{ch:Lfun}
|
|
|
\index{subject}{function}
|
|
|
|
|
|
-This chapter studies the compilation of a subset of \racket{Typed
|
|
|
+This chapter studies the compilation of a subset of \racket{Typed
|
|
|
Racket}\python{Python} in which only top-level function definitions
|
|
|
-are allowed..
|
|
|
-This kind of function is a realistic example as the C language imposes
|
|
|
-similar restrictions. It is also an important stepping stone to
|
|
|
-implementing lexically-scoped functions in the form of \key{lambda}
|
|
|
-abstractions, which is the topic of Chapter~\ref{ch:Llambda}.
|
|
|
+are allowed. This kind of function appears in the C programming
|
|
|
+language and it serves as an important stepping stone to implementing
|
|
|
+lexically-scoped functions in the form of \key{lambda} abstractions,
|
|
|
+which is the topic of Chapter~\ref{ch:Llambda}.
|
|
|
|
|
|
\section{The \LangFun{} Language}
|
|
|
|
|
|
The concrete and abstract syntax for function definitions and function
|
|
|
application is shown in Figures~\ref{fig:Lfun-concrete-syntax} and
|
|
|
-\ref{fig:Lfun-syntax}, where we define the \LangFun{} language. Programs in
|
|
|
-\LangFun{} begin with zero or more function definitions. The function
|
|
|
-names from these definitions are in-scope for the entire program,
|
|
|
-including all other function definitions (so the ordering of function
|
|
|
-definitions does not matter).
|
|
|
+\ref{fig:Lfun-syntax}, where we define the \LangFun{} language.
|
|
|
+Programs in \LangFun{} begin with zero or more function definitions.
|
|
|
+The function names from these definitions are in-scope for the entire
|
|
|
+program, including all of the function definitions (so the ordering of
|
|
|
+function definitions does not matter).
|
|
|
%
|
|
|
\python{The abstract syntax for function parameters in
|
|
|
Figure~\ref{fig:Lfun-syntax} is a list of pairs, where each pair
|
|
@@ -13267,7 +13266,7 @@ program applies \code{map} to \code{inc} and
|
|
|
%
|
|
|
The result is \racket{\code{(vector 1 42)}}\python{\code{(1, 42)}},
|
|
|
%
|
|
|
-from which we return the \code{42}.
|
|
|
+from which we return \code{42}.
|
|
|
|
|
|
\begin{figure}[tbp]
|
|
|
{\if\edition\racketEd
|
|
@@ -13322,7 +13321,7 @@ top-level function definitions.
|
|
|
%
|
|
|
To interpret a function \racket{application}\python{call}, we match
|
|
|
the result of the function expression to obtain a function value. We
|
|
|
-then extend the function's environment with mapping of parameters to
|
|
|
+then extend the function's environment with the mapping of parameters to
|
|
|
argument values. Finally, we interpret the body of the function in
|
|
|
this extended environment.
|
|
|
|
|
@@ -13337,10 +13336,6 @@ this extended environment.
|
|
|
(define/override ((interp-exp env) e)
|
|
|
(define recur (interp-exp env))
|
|
|
(match e
|
|
|
- [(Var x) (unbox (dict-ref env x))]
|
|
|
- [(Let x e body)
|
|
|
- (define new-env (dict-set env x (box (recur e))))
|
|
|
- ((interp-exp new-env) body)]
|
|
|
[(Apply fun args)
|
|
|
(define fun-val (recur fun))
|
|
|
(define arg-vals (for/list ([e args]) (recur e)))
|
|
@@ -13429,9 +13424,12 @@ class InterpLfun(InterpLtup):
|
|
|
%\margincomment{TODO: explain type checker}
|
|
|
|
|
|
The type checker for \LangFun{} is in
|
|
|
-Figure~\ref{fig:type-check-Lfun}. (We omit the code that parses
|
|
|
-function parameters into the simpler abstract syntax.) Similar to the
|
|
|
-interpreter, the case for the
|
|
|
+Figure~\ref{fig:type-check-Lfun}.
|
|
|
+%
|
|
|
+\python{(We omit the code that parses function parameters into the
|
|
|
+ simpler abstract syntax.)}
|
|
|
+%
|
|
|
+Similar to the interpreter, the case for the
|
|
|
\racket{\code{ProgramDefsExp}}\python{\code{Module}}
|
|
|
%
|
|
|
AST is responsible for setting up the mutual recursion between the
|
|
@@ -15150,7 +15148,7 @@ 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.
|
|
|
|
|
|
-The main idea of bidirectional type inference is to add an auxilliary
|
|
|
+The main idea of bidirectional type inference is to add an auxiliary
|
|
|
function, here named \code{check\_exp}, that takes an expected type
|
|
|
and checks whether the given expression is of that type. Thus, in
|
|
|
\code{check\_exp}, type information flows in a top-down manner with
|
|
@@ -16396,13 +16394,13 @@ programming language but were initially dynamically scoped. The Scheme
|
|
|
dialect of LISP adopted lexical scoping and
|
|
|
\citet{Guy-L.-Steele:1978yq} demonstrated how to efficiently compile
|
|
|
Scheme programs. However, environments were represented as linked
|
|
|
-lists, so variable lookup was linear in the size of the
|
|
|
+lists, so variable look-up was linear in the size of the
|
|
|
environment. \citet{Appel91} gives a detailed description of several
|
|
|
closure representations. In this chapter we represent environments
|
|
|
using flat closures, which were invented by
|
|
|
\citet{Cardelli:1983aa,Cardelli:1984aa} for the purposes of compiling
|
|
|
the ML language~\citep{Gordon:1978aa,Milner:1990fk}. With flat
|
|
|
-closures, variable lookup is constant time but the time to create a
|
|
|
+closures, variable look-up is constant time but the time to create a
|
|
|
closure is proportional to the number of its free variables. Flat
|
|
|
closures were reinvented by \citet{Dybvig:1987ab} in his Ph.D. thesis
|
|
|
and used in Chez Scheme version 1~\citep{Dybvig:2006aa}.
|
|
@@ -16653,7 +16651,7 @@ length of the vector.
|
|
|
(define ((interp-Rdyn-exp env) ast)
|
|
|
(define recur (interp-Rdyn-exp env))
|
|
|
(match ast
|
|
|
- [(Var x) (lookup x env)]
|
|
|
+ [(Var x) (dict-ref env x)]
|
|
|
[(Int n) (Tagged n 'Integer)]
|
|
|
[(Bool b) (Tagged b 'Boolean)]
|
|
|
[(Lambda xs rt body)
|
|
@@ -20462,5 +20460,41 @@ registers.
|
|
|
% LocalWords: Seq CProgram gensym lib Fprivate Flist tmp ANF Danvy
|
|
|
% LocalWords: rco Flists py rhs unhandled cont immediates lstlisting
|
|
|
% LocalWords: numberstyle Cormen Sudoku Balakrishnan ve aka DSATUR
|
|
|
-% LocalWords: Brelaz eu Gebremedhin Omari deletekeywords min JGS
|
|
|
-% LocalWords: morekeywords fullflexible
|
|
|
+% LocalWords: Brelaz eu Gebremedhin Omari deletekeywords min JGS wb
|
|
|
+% LocalWords: morekeywords fullflexible goto allocator tuples Wailes
|
|
|
+% LocalWords: Kernighan runtime Freiburg Thiemann Bloomington unary
|
|
|
+% LocalWords: eq prog rcl binaryop unaryop definitional Evaluator os
|
|
|
+% LocalWords: subexpression evaluator InterpLint lcl quadwords concl
|
|
|
+% LocalWords: nanopass subexpressions decompositions Lawall Hatcliff
|
|
|
+% LocalWords: subdirectory monadic Moggi mon utils macosx unix repr
|
|
|
+% LocalWords: Uncomment undirected vertices callee Liveness liveness
|
|
|
+% LocalWords: frozenset unordered Appel Rosen pqueue cmp Fortran vl
|
|
|
+% LocalWords: Horwitz Kempe colorable subgraph kx iteratively Matula
|
|
|
+% LocalWords: ys ly Palsberg si JoeQ cardinality Poletto Booleans hj
|
|
|
+% LocalWords: subscriptable MyPy Lehtosalo Listof Pairof indexable
|
|
|
+% LocalWords: bool boolop NotEq LtE GtE refactor els orelse BoolOp
|
|
|
+% LocalWords: boolean initializer param exprs TypeCheckLvar msg Tt
|
|
|
+% LocalWords: isinstance TypeCheckLif tyerr xorq bytereg al dh dl ne
|
|
|
+% LocalWords: le ge cmpq movzbq EFLAGS jle inlined setl je jl Cif
|
|
|
+% LocalWords: lll pred IfStmt sete CFG tsort multigraph FunctionType
|
|
|
+% LocalWords: Wijngaarden Plotkin Logothetis PeytonJones SetBang Ph
|
|
|
+% LocalWords: WhileLoop unboxes Lwhile unbox InterpLwhile rhsT varT
|
|
|
+% LocalWords: Tbody TypeCheckLwhile acyclic mainstart mainconclusion
|
|
|
+% LocalWords: versa Kildall Kleene worklist enqueue dequeue deque tb
|
|
|
+% LocalWords: GetBang effectful SPERBER Lfun tuple implementer's tup
|
|
|
+% LocalWords: indices HasType Lvec InterpLtup tuple's vec ty Ungar
|
|
|
+% LocalWords: TypeCheckLtup Detlefs Tene FromSpace ToSpace Diwan ptr
|
|
|
+% LocalWords: Siebert TupleType endian salq sarq fromspace rootstack
|
|
|
+% LocalWords: uint th vecinit alloc GlobalValue andq bitwise ior elt
|
|
|
+% LocalWords: dereferencing StructDef Vectorof vectorof Lvecof Jacek
|
|
|
+% LocalWords: AllocateArray cheney tospace Dieckmann Shahriyar di xs
|
|
|
+% LocalWords: Shidal Osterlund Gamari lexically FunctionDef IntType
|
|
|
+% LocalWords: BoolType VoidType ProgramDefsExp vals params ps ds num
|
|
|
+% LocalWords: InterpLfun FunRef TypeCheckLfun leaq callee's mainDef
|
|
|
+% LocalWords: ProgramDefs TailCall tailjmp IndirectCallq TailJmp rT
|
|
|
+% LocalWords: prepending addstart addconclusion Cardelli Llambda typ
|
|
|
+% LocalWords: Rlambda InterpLlambda AnnAssign Dunfield bodyT str fvs
|
|
|
+% LocalWords: TypeCheckLlambda annot dereference clos fvts closTy
|
|
|
+% LocalWords: Minamide AllocateClosure Gilray Milner morphos subtype
|
|
|
+% LocalWords: polymorphism untyped AnyType dataclass untag Rdyn
|
|
|
+% LocalWords: lookup
|