Cambridge University Press, Appel, Andrew W., Compiling with continuations / Andrew W. Appel. p. 25 cm. Includes bibliographical references. Then, during CPS transformation, continuations desugar into functions. methods, including the well-known treatments in Appel’s Compiling with Continuations. This book shows how continuation-passing style is used as an intermediate representation to perform optimizations and program transformations. Continuations.
|Genre:||Health and Food|
|Published (Last):||3 June 2006|
|PDF File Size:||7.84 Mb|
|ePub File Size:||16.10 Mb|
|Price:||Free* [*Free Regsitration Required]|
The goal of this article is to introduce CPS transforms in small, individually digestible pieces before stitching them back together as a unified whole.
How to compile with continuations
Continuation-passing style If you’re new to continuation-passing style, I recommend my earlier post on continuation-passing style by example. When a continuation gets allocated, bump the stack pointer.
Code is available in Racket ; techniques applicable to any language. Fortunately, the hybrid CPS transform readily adapts to features like basic values, conditionals, side effects, sequencing and explicit recursion.
To start, split the grammar: Atomic expressions always produce a value and never cause side effects. This simple shift in perspective is economical: During compilation, high-level control constructs ranging from coroutines and exceptions to while loops and break statements steadily desugar into a mixture of two constructs: Examples Even while this transformation is simple, its results are poor.
In the higher-order transform, the function T: The M function only has to watch for lambda terms.
The compkling T expr cont will transform expr into a CPS value, and then construct a call site that applies the term cont to that value:. The transform now has three principal functions: Both of those lambda terms are continuations.
Compiling with Continuations
This is two steps forward, and one step back: The transformation of function application is the main ckntinuations If you’re new to continuation-passing style, I recommend my earlier post on continuation-passing style by example. In the function-application transform, the values of both the function and the argument have to be converted into CPS. If you’re using this in practice, alphatize the program first, or modify letrec to bind the continuation to a variable outside the scope of the letrec.
Ultimately, however, that transformation must run on real code.
The expression T expr cont might be read “the transformation of expr into continuation-passing style, such that cont will be invoked on its result. This transformation is not hygienic ; if the continuation c references any of the ; bound variables!
There are some advantages [and disadvantages] to stackless compilation. Consider an expanded input language: We can even use the stack pointer register. For the first three transforms, the input language is the lambda calculus: In this transformation, we have two functions, M and T: Scaling to real language features The lambda calculus makes a zppel platform for studying the architecture of a program transformation.
Knowing how to convert code into CPS, either by hand or algorithmically, is a powerful weapon in the programmer’s arsenal. To generate a fresh variable bound to a user value, the transform appe, use genusymand for a fresh variables bound to a continuation, the transform will use genksym: In terms of unreasonable effectiveness, the transformation to continuation-passing style CPS ranks with the Y combinator.
More resources Andrew Kennedy points out that CPS is more advantageous as an intermediate form with respect to optimization than had been previously thought. For the fourth transform, it will become partitioned CPS, and for the final transform, it will be a more realistic intermediate language with side effects, conditionals, basic values and explict recursion.
The wrinkle in the previous transform was that it forced function application to bind its function and its arguments to variables, even if they were already atomic. The transformation for letrec is not hygienic, because the transformation can introduce the letrec ‘d bindings into the scope of the continuation that gets passed to the transformer. To generate a fresh variable cintinuations to a user value, the transform will use genusymand for a fresh variables bound to a continuation, the transform will use genksym:.
If the transform receives a real function expecting the atomic version of iwth the supplied expression, then the transform can check whether it is necessary to bind it to a variable.
All calls become tail calls, so in effect, there is no stack.