Typ ed Closure Conversion
Yasuhiko Minamide Greg Morrisett Rob ert Harp er
Research Institute for Mathematical Sciences Scho ol of Computer Science Scho ol of Computer Science
Kyoto University Carnegie Mellon University Carnegie Mellon University
Kyoto 606{01, Japan Pittsburgh, PA 15213{3891 Pittsburgh, PA 15213{3891
[email protected] [email protected] [email protected]
ronments and is thus exploited to go o d advantage byShao Abstract
and App el [31] and Wand and Steckler [38].
We study the typing prop erties of closureconversion for
Most accounts consider closure conversion as a transfor-
simply-typ ed and p olymorphic -calculi . Unlikemostac-
mation to untyped terms, irresp ective of whether or not the
counts of closure conversion, which only treat the untyp ed
source term is typ ed [35, 16, 2, 38]. This is adequate for com-
-calculus, we translate well-typ ed source programs to well-
pilers that make little or no use of typ es in the backendor
typ ed target programs. This allows later compiler phases to
at run time. However, when compiling typ ed languages, it is
take advantage of typ es for representation analysis and tag-
often advantageous to propagate typ e information through
free garbage collection, and it facilitates correctness pro ofs.
each stage of the compiler, and to make use of typ es at link
Our account of closure conversion for the simply-typ ed lan-
or even run time. For example, Leroy's representation analy-
guage takes advantage of a simple mo del of ob jects bymap-
sis [18, 32 ] uses typ es to determine pro cedure calling conven-
ping closures to existentials. Closure conversion for the
tions, and Ohori's record compilation [26] uses a representa-
p olymorphic language requires additional typ e machinery,
tion of typ es at run time to access comp onents of a record.
namely translucency in the style of Harp er and Lillibri dg e's
In current compilers, these phases must o ccur before closure
mo dule calculus, to express the typ e of a closure.
conversion b ecause the output of closure conversion is un-
typ ed. Compilation strategies for p olymorphic languages,
such as those prop osed by Morrison et al. [25] and Harp er
1 Intro duction
and Morrisett [13], rely on analyzing typ es at run time to
supp ort unboxed representations and non-parametric op er-
Closureconversion [30, 35 , 6, 16, 15, 2, 38, 8] is a program
ators, including printing and structural equality.Tag-free
transformation that achieves a separation b etween co de and
garbage collection [4, 37, 24 ] for b oth monomorphic and
data. Functions with free variables are replaced bycode
p olymorphic programming languages also relies up on typ es
abstracted on an extra environment parameter. Free vari-
at run time to determine the size and the p ointers of ob-
ables in the b o dy of the function are replaced by references
jects. To supp ort any of these implementation strategies, it
to the environment. The abstracted co de is \partially ap-
is necessary to propagate typ e information through closure
plied" to an explicitly constructed environmentproviding
conversion and into the generated co de. Consequently,the
the bindings for these variables. This \partial application"
purp ose of this pap er is to showhow closure conversion can
of the co de to its environment is in fact susp ended until the
b e formulated as a type-preserving transform.
function is actually applied to its argument; the susp ended
We are therefore interested in type-basedtransformations
application is called a \closure", a data structure containing
as a basis for compiling p olymorphic languages. The crucial
pure co de and a representation of its environment.
idea is to de ne a compiler as a series of transformations on
A critical decision in closure conversion is the choice of
b oth the program and its typ e, p ossibly relying on typ e in-
representation of the environment as a data structure |
formation to guide the transformation itself. Each stage of
for example, whether to use a \ at", \linked", or hybrid
the compiler is thus viewed as a typ e-preserving translation
representation. This decision is in uenced by a desire to
between typ ed intermediate languages. Examples of such
minimize closure creation time, the space consumed byan
translations are given by Leroy [18], Ohori [26], Harp er and
environment, and the time to access a given variable in an
Lillibri dge [9], and Harp er and Morrisett [13]. In addition
environment [38, 31]. An imp ortant prop erty of closure con-
to the practical advantages of propagating typ e information
version is that the representation of the environmentispri-
through the stages of a compiler, typ e-directed translation
vate to the closure, and is not visible from the outside. This
also facilitates correctness pro ofs by de ning the invariants
a ords considerable exibili ty in the representation of envi-
of the transformation as a typ e-indexed family of logical re-
This researchwas p erformed while the author was visiting the
lations [36, 7, 28, 33, 34].
Fox Pro ject at Carnegie Mellon University.
We describ e closure conversion in two stages. The rst
stage, abstract closureconversion,isa typ e-based transla-
tion from the source language into a target language with
To app ear POPL '96.
explicit closures. The translation is describ ed as a deductive
system in which the representation of the environmentmay
be chosen indep endently for each closure. In this wayvari-
ous environment representations, such as those used bythe p ossible to nd and eliminate compiler bugs since we can au-
CAM [6] and the FAM [5], as wellashybrid strategies, such tomatically typ e-check the output of each compiler phase.
as those suggested by Shao and App el [31] can b e explained Some compilers for ML based on representation analysis
in a uniform framework. [18, 32] also propagate typ e information through closure
The second stage, closurerepresentation,isa typ e-based conversion. However, their information is not enough to
translation in which the implementation of closures is de- typ e-check the resulting programs b ecause p olymorphism
termined. The main idea is to represent closures as objects is implemented by co ercions and all p olymorphic typ es are
(in contrast to the prop osed representation of objects as clo- represented byasingletyp e.
sures [29]). Following Pierce and Turner [27] we consider The remainder of this pap er is organized as follows: In
ob jects to b e packages of existential typ e consisting of a sin- Section 2, we giveanoverview of closure conversion and
gle metho d (the co de part of the closure) together with a the typing issues involved for the simply-typ ed -calculus.
single instance variable (the environment part) whose typ e In Section 3, we provide the details of our typ e-preserving
(the environment representation) is held abstract. This cap- transform for the simply-typ ed case. In Section 4, wegivean
tures the critical \privacy" prop ertyofenvironment repre- overview of closure conversion and the typing issues involved
sentations for closures. In the simply-typ ed case wemake for the predicative fragment of the p olymorphic -calculus.
direct use of Pierce and Turner's mo del of ob jects. In the The formal development of this conversion is given in Section
p olymorphic case wemust in addition exploit the notion of 5.
translucency [10] (or manifest types [19]) to express the typ e
of a p olymorphic closure.
2 Overview of Simply-Typ ed Closure Conversion
The correctness of b oth the abstract closure conversion
and the closure representation stages are proved using the
The main ideas of closure conversion may b e illustrated by
metho d of logical relations. The main idea is to de ne a
considering the following ML program:
typ e-indexed family of simulation relations that establish a
let val x = 1
corresp ondence b etween the source and target terms of the
val y = 2
translation. Once a suitable system of relations has b een
val z = 3
de ned, it is relatively straightforward to proveby induction
val f = w. x + y + w
on the de nition of the compilation relation that the source
in
and target of the translation are related, from whichwemay
f 100
conclude that a closed program and its compilation evaluate
end
to the same result. Due to a lack of space, the pro ofs of
correctness are omitted here. However, full details are given
The function f contains free variables x and y,butnotz.
in the companion technical rep ort [22].
Wemay eliminate the references to these variables from the
Closure conversion is discussed in descriptions of various
body of f by abstracting on an environment env, and replac-
functional language compilers [35, 16 , 3, 2 , 31]. It is closely
ing x and y by references to the environment. In comp en-
related to -lifting [14] in that it eliminates free variables in
sation a suitable environmentcontaining the bindings for x
the b o dies of -abstractions but di ers by making the rep-
and y must b e passed to f b efore it is applied. This leads
resentation of the environment explicit as a data structure.
to the following translation:
Making the environment explicit is imp ortant b ecause it ex-
p oses environment construction and variable lo okup to an
let val x = 1
optimizer. Furthermore, Shao and App el show that not all
val y = 2
environment representations are \safe for space" [31], and
val z = 3
thus cho osing a go o d environment representation is an im-
val f = (env. w. (#x env) + (#y env) + w)
p ortant part of compilation. Wand and Steckler [38] have
fx=x, y=yg
consider two optimizations of the basic closure conversion
in
strategy, called selective and lightweight closure conversion,
f 100
and provide a correctness pro of for each of these in an un-
end
typ ed setting. Hannan [8] re-casts Wand's work into a typ ed
References to x and y in the b o dy of f are replaced by
setting, and provides correctness pro ofs for Wand's opti-
pro jections ( eld selections) #x and #y that access the corre-
mizations. Hannan's translation is given, like ours, as a de-
sp onding comp onent of the environment. Since the co de for
ductive system, but like -lifting, he do es not consider the
f is closed, it may b e hoisted out of the enclosing de nition
imp ortant issue of environment representation (preferring an
and de ned at the top-level. We ignore this \hoisting" phase
abstract account), nor do es he consider the typing prop er-
and instead concentrate on the pro cess of closure conversion.
ties of the closure-converted co de. Finally, neither Wand nor
These simple translations fail to delay the application of
Hannan consider closure conversion under a typ e-passing in-
the co de to its environment under call-by-value evaluation.
terpretation of p olymorphis m.
A natural representation of a delayed application or closure
Wehave put the ideas in this pap er to practical use in
is an ordered pair (code, env) consisting of the co de to-
two separate compilers for ML: one compiler is b eing used
gether with its environment. Application of a closure to
to study novel approaches to tag-free garbage collection and
an argument pro ceeds by pro jecting the co de part from the
the other compiler provides a general framework for analyz-
closure and applying it simultaneousl y to the environment
ing typ es at run time to determine the shap es of ob jects.
and the argument according to some calling convention. For
Propagating typ es through closure conversion is necessary
example:
for b oth compilers so that typ es can b e examined at run
time. Wehave also found that typ ed closure conversion,
along with our other typ e-preserving translations, made it 2
let val x = 1 Since the typ es of the arms of the if-expression agree, the
val y = 2 target co de is well-typ ed with typ e 9t :(t ! int ! int)
ve ve
val z = 3 t .
ve
val code = env. w. #x(env) + #y(env) + w An application ee'is corresp ondingl y translated to the
val env = fx=x, y=yg expression
val f = (code, env)
open e as t with z : (t ! ! ) t
ve ve 1 2 ve
in
in
(#1 f) (#2 f) 100
(#1 z) (#2 z) e'
end
end
But since code has a typ e of the form ! ! , where
ve 1 2
is the typ e of the environment env, the closure as a
ve which opens the package, extracts the co de and environ-
whole would havetyp e ( ! ! ) , showing
ve 1 2 ve
ment, and applies the co de to the environment and the ar-
the typ e of the environment explicitl y. That violates the
gument.
\privacy" of the environment representation. As a result,
This representation of closures b ears a striking resem-
using this translation on a well-typ ed source program will
blance to the mo del of ob jects suggested byPierceand
not, in general, result in a well-typ ed target program. For
Turner [27]. In their mo del an ob ject has a typ e of the form
example, consider the following ML source program with
9t:t [t], where t is the typ e of the instance variable(s) and
typ e int ! int:
[t] is the typ e of the metho d(s). According to the forego-
ing account, closures may b e thought of as ob jects with one
let val y = 1
instance variable (the environment) and one metho d (the
in
co de).
if true then
x. x+y
else
3 AFormal Account of Simply-Typ ed Closure Conversion
z. z
end
In this section we present the details of closure conversion for
Performing the translation ab ove yields:
the call-by-value, simply-typ ed -calculus. The conversion
let val y = 1
is describ ed in increasing detail by three stages: The rst
in
stage, abstract closureconversion,converts each function to
if true then
a closure but holds the representation of the closure abstract.
(env. x. x + #y(e), fy=yg)
To simplify the presentation, some freedom is allowed in the
else
construction of environments, but no shared environments
(env. z. z, fg)
are used. The second stage, environment sharing, adds more
end
structure to the translation thereby allowing environments
This program fails to typ e-check b ecause the then-arm of to b e shared. The third stage, closurerepresentation, makes
the representation of closures explicit through the use of
the if-expression has typ e (fy:intg!int ! int) fy:intg
translucent sums. Each stage is de ned as a typ e-directed
while the else-arm has typ e (fg ! int ! int) fg.
translation and the correctness of the translations is estab-
In order to preservetyp es in the target language, the
lished using logical relations.
representation of the environmentmay b e hidden using ex-
The syntax of the source language is de ned as follows:
istential typ es [23]. Figure 1 gives the typing rules for exis-
tentials. A pack op eration pairs a typ e with a value e as
Types ::= b j !
1 2
an existential, holding abstract as a typ e variable, t.An
Expressions e ::= c j x j x:: e j e e
1 2
open op eration takesapackage e and op ens it, binding the
1
Values v ::= c j x:: e
abstract typ e to t and the value of the package to x within
the scop e of e . The abstract typ e t is constrained so that
2
1
Typ es ( ) consist of base typ es (b) and function typ es (!) .
it cannot leave the scop e of the open construct, hence the
Expressions (e) consist of constants (c) of base typ e, vari-
restriction that t not app ear in the free typ e variables of .
ables, abstractions, and application s. Weuse todenote
Using pack,we can hide the typ e of the environment for
a sequence of typ e bindings of the form fx : ;::: ;x : g,
a closure value as follows: 1 1 n n
(n 0) where the x are distinct. The judgement ` e :
i
pack with (code; env) as 9t :(t ! ! ) t :
ve ve ve 1 2 ve
asserts that the expression e has typ e under the typ e as-
signment , and is derived from the standard typing rules of
A closure of typ e ! is represented as a package of typ e
1 2
the simply-typ ed -calculus. We de ne the dynamic seman-
9t :(t ! ! ) t where the typ e of the environment
ve ve 1 2 ve
tics of the language using a judgement of the form e,! v (e
( ) is held abstract as t . Under this translation, the
ve ve
evaluates to v ). The judgement is derived from the following
example ab ovewould b e translated to:
standard inference rules for call-by-value evaluation:
let val y = 1
in
e ,! x: :e e ,! v e[v =x] ,! v
1 1 2 2 2
if true then
v,! v
e e ,! v
1 2
pack fy:intg with (env. x. x+#y(env),fy=yg)
1
as 9t :(t ! int ! int) t
ve ve ve
The results of this pap er easily extended to other source typ es
else
including pro ducts and sums.
pack fg with (env. z. z, fg)
as 9t :(t ! int ! int) t
ve ve ve
end 3
0
; ` e : 9t:
1
; ` e : [=t]
0
]ftg; ]fx: g`e :
(t 62 FTV ( );t 62 )
2
; ` pack with e as 9t:
; ` open e as t with x in e :
1 2
Figure 1: Typing Rules for Existentials
0 0 0
is an expression that eval- asserts that e ; x:. ; e 3.1 Abstract Closure Conversion
ve ve
0
uates to the environment corresp onding to under the as-
cl
The target language for abstract closure conversion, ,is
0
sumption that each binding in o ccurs in ]fx: g. Note
de ned as follows:
that the order of bindings in is imp ortant, and thus it is
considered to b e a sequence and not a set.
Types ::= b j ! jh ::: ijcode( ; ; )
1 2 1 n ve 1 2
In a translated expression, x is always used to hold the
ve
Exp's e ::= c j x j e e jhe ;:::; e ij (e) j
1 2 1 n i
currentlocalenvironment. Consequently, the translation
x : :x: :e jhhe ;e ii
ve ve 1 1 2
th
rule (env) maps a source variable x found in the i p osition
i
Values v ::= c j x : :x: :e jhv ;:::;v ij hhv ;v ii
ve ve 1 1 n 1 2
th
of typ e assignment to the i pro jection of the environment
In the intro duction we informally presented closures as par-
variable x , while the rule (arg) translates the argument
ve
tial applicati ons. As noted, we wish to delay this partial ap-
variable x to itself.
plication until the closure is applied to an argument, so that
The translation of an abstraction pro duces a closure con-
the co de and environment remain separate and the co de can
sisting of co de and an environment. To construct the envi-
0 0 0
b e shared among each instantiatio n of the closure. There-
ronment, wecho ose a typ e assignment suchthat ;x : .
0 0
fore, in this account of closure conversion, we representthe