Automatic autoprojection of higher order recursive equations [chapter]

Anders Bondorf
1990 Lecture Notes in Computer Science  
A b s t r a c t Autoprojection, or self-applicable partial evaluation, has been implemented for first order functio-naI languages for some years now. This paper describes an approach to treat a higher order subset of the Scheme language. The system has been implemented as an extension to the existing autoprojector Similix [Bondoff & Danvy 90] that treats a first order Scheme subset. To our knowledge, our system is the first fully automatic and implemented autoprojector for a higher order
more » ... e. Given a source program and some, but not all of its inputs, partial evaluation produces a residual program. When applied to the rest of the inputs, the residual program yields the same result as the source program would when applied to all inputs. One important application of autoprojection is semantics directed compiler generation: given a denc~ tational, interpretive specification of a programming language, it is possible automatically to generate a stand-alone compiler by self-applying the partial evaluator. Efficient autoprojection is known to require binding time analysing source programs to be partially evaluated. Binding time analysis establishes in advance which parts of the source program that can be evaluated during partial evaluation and which parts that cannot. We describe a new automatic binding time analysis for higher order pro-* This work was carried out while the author was staying at . The work was partly supported by the Danish ~h Academy. grams written in the Scheme subset. The analysis requires no type information. It is based on a closure analysis [Sestoft 88b], which for any application point finds the set of lambda abstractions that can possibly be applied at that point. The binding time analysis has the interesting property that no structured binding time values are needed. Since our language is higher order, interpreters written in a higher order style can be partially evaluated. To exemplify this, we present and partially evaluate three versions of an interpreter for a lambda calculus language: one written in direct style, one written in continuation passing style, and one implementing normal order reduction. The two latter are heavily based on higher order programming. K e y w o r d s Partial evaluation, self-application, binding time analysis, semantics directed compiler generation. I n t r o d u c t i o n Partial evaluation is a program transformation that specializes programs: given a source program and a part of its input (the static input), a partial evaluator generates a residual program. When applied to the remaining input (the dynamic input), the residual program yields the same result as the source program would when applied to all of the input. Autoprojection is a synonym for self-applicable partial evaluation, that is, specialization of the partial evaluator itself. It was established in the seventies that autoprojection can be used for automatic semantics directed compiler generation: specializ-71 ing a partial evaluator with static input being (the text of) an interpreter for some programming language S yields a compiler for S [Futamura 71] [Er- shov 77] [Turchin 80]. Specializing the partial evaluator with static input being (the text of) the partial evaluator itself even yields a compiler generator (antomatic compiler generator generation!). The first successfully implemented autoprojector was Miix [Jones, Sestoft, & S0ndergaard 85]. The language treated by Mix was a subset of statically scoped first order pure Lisp, and Mix was able to generate compilers out of interpreters written in this language. The experiment showed that autoprojecdon was possible in practice; an automatic version of Mix was developed later [Jones, Sestort, & S0ndergaard 89]. Since then, autoprojectors for several languages have been implemented: for a subset of Turchin's Refal language [Romanenko 88], for an imperative flowchart language [Gomard & Jones 89], for pattern matching based programs in the form of restricted term rewriting systems [Bondorf 89], and for first order functional langu~Lges with global variables [Bondorf & Danvy 90]. Autoprojecting higher order languages The first autoprojector for a higher order functional language is (to our knowledge) Lambda-mix [Gomard 89] [JonGomBonDanMog 90]. Lambda-mix treats the untyped call-by-value lambda calculus. The system is surprisingly simple and easy to Understand; even the generated compilers are small and readable (which is quite uncommon for compilers generated by autoprojectors!). However, a strong limitation in Lambda-mix is that static parameters of recursive functions must be induction variables [Aho, Sethi, & Ullman 86]; non-inductive variables are always dynamic. Lambda-mix thus does not specialize (recursive) calls to equal functions 'with equal patterns of static argument values (known as polyvariant program specialization [Bulyonkov 84]). Specialization is a kind of folding and thus gives sharing of functions in residual programs. Since Lambda-mix does not specialize calls, it does not perform well for some applications. For instance, when using partial evaluation to generate string pattern matchers [Consel & Danvy 89], non-inductive recursive static variables are used. In this paper we describe an implemented automatic autoprojector, Similix-2, that handles a higher order subset of the Scheme language [Rees & Clinger 86], essentially weakly (dynamically) typed, statically scoped, call-by-value recursive equations with lambda abstractions and applications. Similix-2 uses polyvariant program specialization and is, to our knowledge, the first fully automated and implemented autoprojector for a higher order language (Lambda-mix requires handwritten binding time annotations; an automatic version has been developed later [Gomard 90]). Similix-2 has been developed and implemented by extending Similix [Bondorf & Danvy 90], an existing autoprojector for a first order Scheme subset. Similix-2 therefore has a number of features that have been inherited from Similix: side-effecting operations on global variables (such as i/o operations) are treated in a semantically correct way; primitives are user specified (as introduced in [Consel 88]), i.e. there is no fixed set of primitives; residual programs never duplicate computations (cf. call duplication [Sestoft 88a]); residual programs do not terminate more often than source programs; call unfolding is controlled automatically (by a simple strategy based on detecting dynamic conditionals). This paper does not cover these aspects which all come from Similix; we refer to [Bondorf & Danvy 90] (and to [Bondorf 90]). Treating higher order languages opens new perspectives for using autoprojection for semantics directed compiler generation: Similix-2 treats interpreters written in continuation passing style and interpreters that implement (weak head) normal order reduction (outside-in, call-by-name) by "thunks" of the form (L O E). We exemplify this by specializing such interpreters. To our knowledge, this is the first time autoprojection has been used to generate compilers from interpreters of that kind. Outline The rest of the paper is organized as follows. Section 2 gives some background and introduces the main issues of this paper. In section 3, we present an interpreter for a lambda calculus language "A". The interpreter serves as an example of a higher 72 order program; when it is specialized, programs in the A-language are in effect compiled. The sections 4 and 5 contain the technical part: we develop/describe two pre-analyses needed for partial evaluation of higher order programs; both analyses are presented formally in a compositional denotational semantics style. In section 6, we exemplify partial evaluation of higher order programs: the Ainterpreter is specialized, and we also specialize two other A-interpreters: one written in continuation passing style and one implementing normal order reduction. The performance of the system is shown in section 7. Section 8 is a discussion, and in section 9 we conclude and sketch some open problems.
doi:10.1007/3-540-52592-0_56 fatcat:xpawd7jw4jfshgcncmom3eao5m