An Operational Foundation for Delimited Continuations in the CPS Hierarchy

We present an abstract machine and a reduction semantics for the lambda-calculus extended with control operators that give access to delimited continuations in the CPS hierarchy. The abstract machine is derived from an evaluator in continuation-passing style (CPS); the reduction semantics (i.e., a small-step operational semantics with an explicit representation of evaluation contexts) is constructed from the abstract machine; and the control operators are the shift and reset family. We also present new applications of delimited continuations in the CPS hierarchy: finding list prefixes and normalization by evaluation for a hierarchical language of units and products.

The original motivation for shift and reset was a continuation-based programming pattern involving several layers of continuations. The original specification of these operators relied both on a repeated CPS transformation and on an evaluator with several layers of continuations (as is obtained by repeatedly transforming a direct-style evaluator into continuationpassing style). Only subsequently have shift and reset been specified operationally, by developing operational analogues of a continuation semantics and of the CPS transformation [31].
The goal of our work here is to establish a new operational foundation for delimited continuations, using CPS as a guideline. To this end, we start with the original evaluator for shift 1 and reset 1 . This evaluator uses two layers of continuations: a continuation and a meta-continuation. We then defunctionalize it into an abstract machine [1] and we construct the corresponding reduction semantics [35], as pioneered by Felleisen and Friedman [38]. The development scales to shift n and reset n . It is reusable for any control operators that are compatible with CPS, i.e., that can be characterized with a (possibly iterated) CPS translation or with a continuation-based evaluator. It also pinpoints where operational intuitions go beyond CPS.
This article is structured as follows. In Section 2, we review the enabling technology of our work: Reynolds's defunctionalization, the observation that a defunctionalized CPS program implements an abstract machine, and the observation that Felleisen's evaluation contexts are the defunctionalized continuations of a continuation-passing evaluator; we demonstrate this enabling technology on a simple example, arithmetic expressions. In Section 3, we illustrate the use of shift and reset with the classic example of finding list prefixes, using an MLlike programming language. In Section 4, we then present our main result: starting from the original evaluator for shift and reset, we defunctionalize it into an abstract machine; we analyze this abstract machine and construct the corresponding reduction semantics. In Section 5, we extend this result to the CPS hierarchy. In Section 6, we illustrate the CPS hierarchy with a class of normalization functions for a hierarchical language of units and products.
2. we defunctionalize the CPS evaluator, obtaining a value-based abstract machine; 3. we modify the abstract machine to make it term-based instead of value-based; in particular, if the evaluator uses an environment, then so does the corresponding value-based abstract machine, and in that case, making the machine term-based leads us to use substitutions rather than an environment; 4. we analyze the transitions of the term-based abstract machine to identify the evaluation strategy it implements and the set of reductions it performs; the result is a reduction semantics.
The first two steps are based on previous work on a functional correspondence between evaluators and abstract machines [1-3, 16, 25], which itself is based on Reynolds's seminal work on definitional interpreters [67]. The last two steps follow the lines of Felleisen and Friedman's original work on a reduction semantics for the call-by-value λ-calculus extended with control operators [38]. The last step has been studied further by Hardin, Maranget, and Pagano [48] in the context of explicit substitutions and by Danvy and Nielsen [30].
In the rest of this section, our running example is the language of arithmetic expressions, formed using natural numbers (the values) and additions (the computations): exp e ::= m | e 1 + e 2

The starting point: an evaluator in direct style
We define an evaluation function for arithmetic expressions by structural induction on their syntax. The resulting direct-style evaluator is displayed in Figure 1.

CPS transformation
We CPS-transform the evaluator by naming intermediate results, sequentializing their computation, and introducing an extra functional parameter, the continuation [28,64,72]. The resulting continuation-passing evaluator is displayed in Figure 2.

Defunctionalization
The generalization of closure conversion [57] to defunctionalization is due to Reynolds [67]. The goal is to represent a functional value with a first-order data structure. The means is to partition the function space into a first-order sum where each summand corresponds to a lambda-abstraction in the program. In a defunctionalized program, function introduction is thus represented as an injection, and function elimination as a call to a first-order apply function implementing a case dispatch. In an ML-like functional language, sums are represented as data types, injections as data-type constructors, and apply functions are defined by case over the corresponding data types [29].
Here, we defunctionalize the continuation of the continuation-passing evaluator in Figure 2. We thus need to define a first-order algebraic data type and its apply function. To this end, we enumerate the lambda-abstractions that give rise to the inhabitants of this function space; there are three: the initial continuation in evaluate and the two continuations in eval. The initial continuation is closed, and therefore the corresponding algebraic constructor is nullary. The two other continuations have two free variables, and therefore the corresponding • Functions eval : exp × cont → val and apply cont : cont × val → val:

Abstract machines as defunctionalized continuation-passing programs
Elsewhere [1,25], we have observed that a defunctionalized continuation-passing program implements an abstract machine: each configuration is the name of a function together with its arguments, and each function clause represents a transition. (As a corollary, we have also observed that the defunctionalized continuation of an evaluator forms what is known as an 'evaluation context' [24,29,38].) Indeed Plotkin's Indifference Theorem [64] states that continuation-passing programs are independent of their evaluation order. In Reynolds's words [67], all the subterms in applications are 'trivial'; and in Moggi's words [60], these subterms are values and not computations. Furthermore, continuation-passing programs are tail recursive [72]. Therefore, since in a continuation-passing program all calls are tail calls and all subcomputations are elementary, a defunctionalized continuation-passing program implements a transition system [65], i.e., an abstract machine.
We thus reformat Figure 3 into Figure 4. The correctness of the abstract machine with respect to the initial evaluator follows from the correctness of CPS transformation and of defunctionalization.

From value-based abstract machine to term-based abstract machine
We observe that the domain of expressible values in Figure 4 can be embedded in the syntactic domain of expressions. We therefore adapt the abstract machine to work on terms rather than on values. The result is displayed in Figure 5; it is a syntactic theory [35].

From term-based abstract machine to reduction semantics
The method of deriving a reduction semantics from an abstract machine was introduced by Felleisen and Friedman [38] to give a reduction semantics for control operators. Let us demonstrate it.
We analyze the transitions of the abstract machine in Figure 5. The second component of eval-transitions-the stack representing "the rest of the computation"-has already been identified as the evaluation context of the currently processed expression. We thus read a configuration e, C eval as a decomposition of some expression into a sub-expression e and an evaluation context C.
Next, we identify the reduction and decomposition rules in the transitions of the machine. Since a configuration can be read as a decomposition, we compare the left-hand side and the right-hand side of each transition. If they represent the same expression, then the given transition defines a decomposition (i.e., it searches for the next redex according to some evaluation strategy); otherwise we have found a redex. Moreover, reading the decomposition rules from right to left defines a 'plug' function that reconstructs an expression from its decomposition.
Here the decomposition function as read off the abstract machine is total. In general, however, it may be undefined for stuck terms; one can then extend it straightforwardly into a total function that decomposes a term into a context and a potential redex, i.e., an actual redex (as read off the machine), or a stuck redex.
• Values: v ::= m • Evaluation contexts: C :: • Initial transition, transition rules, and final transition: • Initial transition, transition rules, and final transition: In this simple example there is only one reduction rule. This rule performs the addition of natural numbers: The remaining transitions decompose an expression according to the left-to-right strategy.

From reduction semantics to term-based abstract machine
In Section 2.6, we have constructed the reduction semantics corresponding to the abstract machine of Figure 5, as pioneered by Felleisen and Friedman [37,38]. Over the last few years [23,30], Danvy and Nielsen have studied the converse transformation and systematized the construction of an abstract machine from a reduction semantics. The main idea is to short-cut the decompose-contract-plug loop, in the definition of evaluation as the transitive closure of one-step reduction, into a refocus-contract loop. The refocus function is constructed as an efficient (i.e., deforested) composition of plug and decompose that maps a term and a context either to a value or to a redex and a context. The result is a 'pre-abstract machine' computing the transitive closure of the refocus function. This pre-abstract machine can then be simplified into an eval/apply abstract machine.
It is simple to verify that using refocusing, one can go from the reduction semantics of Section 2.6 to the eval/apply abstract machine of Figure 5.

Summary and conclusion
We have demonstrated how to derive an abstract machine out of an evaluator, and how to construct the corresponding reduction semantics out of this abstract machine. In Section 4, we apply this derivation and this construction to the first level of the CPS hierarchy, and in Section 5, we apply them to an arbitrary level of the CPS hierarchy. But first, let us illustrate how to program with delimited continuations.

Programming with delimited continuations
We present two examples of programming with delimited continuations. Given a list xs and a predicate p, we want 1. to find the first prefix of xs whose last element satisfies p, and 2. to find all such prefixes of xs. In Section 3.1, we start with a simple solution that uses a first-order accumulator. This simple solution is in defunctionalized form. In Section 3.2, we present its higher-order counterpart, which uses a functional accumulator. This functional accumulator acts as a delimited continuation. In Section 3.3, we present its direct-style counterpart (which uses shift and reset) and in Section 3.4, we present its continuation-passing counterpart (which uses two layers of continuations). In Section 3.5, we introduce the CPS hierarchy informally. We then mention a typing issue in Section 3.6 and review related work in Section 3.7.

Finding prefixes by accumulating lists
A simple solution is to accumulate the prefix of the given list in reverse order while traversing this list and testing each of its elements: • if no element satisfies the predicate, there is no prefix and the result is the empty list; • otherwise, the prefix is the reverse of the accumulator. To find the first prefix, one stops as soon as a satisfactory list element is found. To list all the prefixes, one continues the traversal, adding the current prefix to the list of the remaining prefixes.
We observe that the two solutions are in defunctionalized form [29,67]: the accumulator has the data type of a defunctionalized function and reverse is its apply function. We present its higher-order counterpart next [52].

Finding prefixes by accumulating list constructors
Instead of accumulating the prefix in reverse order while traversing the given list, we accumulate a function constructing the prefix: • if no element satisfies the predicate, the result is the empty list; • otherwise, we apply the functional accumulator to construct the prefix. To find the first prefix, one applies the functional accumulator as soon as a satisfactory list element is found. To list all such prefixes, one continues the traversal, adding the current prefix to the list of the remaining prefixes.
Defunctionalizing these two definitions yields the two definitions of Section 3.1.
The functional accumulator is a delimited continuation: • In find first prefix c 1 , visit is written in CPS since all calls are tail calls and all subcomputations are elementary. The continuation is initialized in the initial call to visit, discarded in the base case, extended in the induction case, and used if a satisfactory prefix is found.
• In find all prefixes c 1 , visit is almost written in CPS except that the continuation is composed if a satisfactory prefix is found: it is used twice-once where it is applied to the empty list to construct a prefix, and once in the visit of the rest of the list to construct a list of prefixes; this prefix is then prepended to the list of prefixes.
These continuation-based programming patterns (initializing a continuation, not using it, or using it more than once as if it were a composable function) have motivated the control operators shift and reset [27,28]. Using them, in the next section, we write visit in direct style.

Finding prefixes in direct style
The two following local functions are the direct-style counterpart of the two local functions in Section 3.2: In both cases, visit is in direct style, i.e., it is not passed any continuation. The initial calls to visit are enclosed in the control delimiter reset (noted · for conciseness). In the base cases, the current (delimited) continuation is captured with the control operator shift (noted S), which has the effect of emptying the (delimited) context; this captured continuation is bound to an identifier k, which is not used; nil is then returned in the emptied context. In the induction case of find all prefixes c 0 , if the predicate is satisfied, visit captures the current continuation and applies it twice-once to the empty list to construct a prefix, and once to the result of visiting the rest of the list to construct a list of prefixes; this prefix is then prepended to the list of prefixes.
CPS-transforming these two local functions yields the two definitions of Section 3.2 [28].

The CPS hierarchy
If k 2 were used non-tail recursively in a variant of the examples of Section 3.4, we could CPS-transform the definitions one more time, adding one more layer of continuations and restoring the syntactic characterization of all calls being tail calls and all sub-computations being elementary. We could also map this definition back to direct style, eliminating k 2 but accessing it with shift. If the result were mapped back to direct style one more time, k 2 would then be accessed with a new control operator, shift 2 , and k 1 would be accessed with shift (more precisely shift 1 ).
All in all, successive CPS-transformations induce a CPS hierarchy [27,31], and abstracting control up to each successive layer is achieved with successive pairs of control operators shift and reset-reset to initialize the continuation up to a level, and shift to capture a delimited continuation up to this level. Each pair of control operators is indexed by the corresponding level in the hierarchy. Applying a captured continuation packages all the current layers on the next layer and restores the captured layers. When a captured continuation completes, the packaged layers are put back into place and the computation proceeds. (This informal description is made precise in Section 4.)

A note about typing
The type of find all prefixes c 1 , in Section 3.2, is (α → bool ) × α list → α list list and the type of its local function visit is In this example, the co-domain of the continuation is not the same as the co-domain of visit.
Thus find first prefix c 0 provides a simple and meaningful example where Filinski's typing of shift [41] does not fit, since it must be used at type ((β → ans) → ans) → β for a given type ans, i.e., the answer type of the continuation and the type of the computation must be the same. In other words, control effects are not allowed to change the types of the contexts. Due to a similar restriction on the type of shift, the example does not fit either in Murthy's pseudo-classical type system for the CPS hierarchy [62] and in Wadler's most general monadic type system [77,Section 3.4]. It however fits in Danvy and Filinski's original type system [26] which Ariola, Herbelin, and Sabry have recently embedded in classical subtractive logic [5].

Related work
The example considered in this section builds on the simpler function that unconditionally lists the successive prefixes of a given list. This simpler function is a traditional example of delimited continuations [20,69]: • In the Lisp Pointers [20], Danvy presents three versions of this function: a typed continuation-passing version (corresponding to Section 3.2), one with delimited control (corresponding to Section 3.3), and one in assembly language.
• In his PhD thesis [69, Section 6.3], Sitaram presents two versions of this function: one with an accumulator (corresponding to Section 3.1) and one with delimited control (corresponding to Section 3.3).
In Section 3.2, we have shown that the continuation-passing version mediates the version with an accumulator and the version with delimited control since defunctionalizing the continuationpassing version yields one and mapping it back to direct style yields the other.

Summary and conclusion
We have illustrated delimited continuations with the classic example of finding list prefixes, using CPS as a guideline. Direct-style programs using shift and reset can be CPS-transformed into continuation-passing programs where not all calls are tail calls and all sub-computations are elementary. One more CPS transformation establishes this syntactic property with a second layer of continuations. Further CPS transformations provide the extra layers of continuation that are characteristic of the CPS hierarchy.
In the next section, we specify the λ-calculus extended with shift and reset.

From evaluator to reduction semantics for delimited continuations
We derive a reduction semantics for the call-by-value λ-calculus extended with shift and reset, using the method demonstrated in Section 2. First, we transform an evaluator into an environment-based abstract machine. Then we eliminate the environment from this abstract machine, making it substitution-based. Finally, we read all the components of a reduction semantics off the substitution-based abstract machine. Terms consist of integer literals, variables, λ-abstractions, function applications, applications of the successor function, reset expressions, and shift expressions: Programs are closed terms.
This source language is a subset of the language used in the examples of Section 3. Adding the remaining constructs is a straightforward exercise and does not contribute to our point here. Figure 6 displays an evaluator for the language of the first level of the CPS hierarchy. This evaluation function represents the original call-by-value semantics of the λ-calculus with shift and reset [27], augmented with integer literals and applications of the successor function. It is defined by structural induction over the syntax of terms, and it makes use of an environment e, a continuation k 1 , and a meta-continuation k 2 .

An environment-based evaluator
• Terms: term t : • Answers, meta-continuations, continuations and functions: • Initial continuation and meta-continuation: • Main function: evaluate : term → val evaluate (t) = eval (t, e empty , θ 1 , θ 2 ) Figure 6: An environment-based evaluator for the first level of the CPS hierarchy The evaluation of a terminating program that does not get stuck (i.e., a program where no ill-formed applications occur in the course of evaluation) yields either an integer, a function representing a λ-abstraction, or a captured continuation. Both evaluate and eval are partial functions to account for non-terminating or stuck programs. The environment stores previously computed values of the free variables of the term under evaluation.
The meta-continuation intervenes to interpret reset expressions and to apply captured continuations. Otherwise, it is passively threaded through the evaluation of literals, variables, λ-abstractions, function applications, and applications of the successor function. (If it were not for shift and reset, and if eval were curried, k 2 could be eta-reduced and the evaluator would be in ordinary continuation-passing style.) The reset control operator is used to delimit control. A reset expression t is interpreted by evaluating t with the initial continuation and a meta-continuation on which the current continuation has been "pushed." (Indeed, and as will be shown in Section 4.2, defunctionalizing the meta-continuation yields the data type of a stack [29].) The shift control operator is used to abstract (delimited) control. A shift expression Sk.t is interpreted by capturing the current continuation, binding it to k, and evaluating t in an environment extended with k and with a continuation reset to the initial continuation. Applying a captured continuation is achieved by "pushing" the current continuation on the meta-continuation and applying the captured continuation to the new meta-continuation. Resuming a continuation is achieved by reactivating the "pushed" continuation with the corresponding meta-continuation.

An environment-based abstract machine
The evaluator displayed in Figure 6 is already in continuation-passing style. Therefore, we only need to defunctionalize its expressible values and its continuations to obtain an abstract machine. This abstract machine is displayed in Figure 7.
The abstract machine consists of three sets of transitions: eval for interpreting terms, cont 1 for interpreting the defunctionalized continuations (i.e., the evaluation contexts), 1 and cont 2 for interpreting the defunctionalized meta-continuations (i.e., the meta-contexts). The set of possible values includes integers, closures and captured contexts. In the original evaluator, the latter two were represented as higher-order functions, but defunctionalizing expressible values of the evaluator has led them to be distinguished.
This eval/apply abstract machine is an extension of the CEK machine [38] with the metacontext C 2 and its two transitions, and the two transitions for shift and reset. C 2 intervenes to process reset expressions and to apply captured continuations. Otherwise, it is passively threaded through the processing of literals, variables, λ-abstractions, function applications, and applications of the successor function. (If it were not for shift and reset, C 2 and its transitions could be omitted and the abstract machine would reduce to the CEK machine.) Given an environment e, a context C 1 , and a meta-context C 2 , a reset expression t is processed by evaluating t with the same environment e, the empty context •, and a metacontext where C 1 has been pushed on C 2 .
Given an environment e, a context C 1 , and a meta-context C 2 , a shift expression Sk.t is processed by evaluating t with an extension of e where k denotes C 1 , the empty context [ ], and a meta-context C 2 . Applying a captured context C 1 is achieved by pushing the current context C 1 on the current meta-context C 2 and continuing with C 1 . Resuming a context C 1 is achieved by popping it off the meta-context C 2 · C 1 and continuing with C 1 .
The correctness of the abstract machine with respect to the evaluator is a consequence of the correctness of defunctionalization. In order to express it formally, we define a partial function eval e mapping a term t to a value v whenever the environment-based machine, started with t, stops with v. The following theorem states this correctness by relating observable results: Proof. The theorem follows directly from the correctness of defunctionalization [10,63]. 1 The grammar of evaluation contexts in Figure 7 is isomorphic to the grammar of evaluation contexts in the standard inside-out notation: • Terms: t : • Values (integers, closures, and captured continuations) • Evaluation contexts: • Initial transition, transition rules, and final transition: The environment-based abstract machine can serve both as a foundation for implementing functional languages with control operators for delimited continuations and as a stepping stone in theoretical studies of shift and reset. In the rest of this section, we use it to construct a reduction semantics of shift and reset.
• Terms and values: t : • Initial transition, transition rules, and final transition:

A substitution-based abstract machine
The environment-based abstract machine of Figure 7, on which we want to base our development, makes a distinction between terms and values. Since a reduction semantics is specified by purely syntactic operations (it gives meaning to terms by specifying their rewriting strategy and an appropriate notion of reduction, and is indeed also referred to as 'syntactic theory'), we need to embed the domain of values back into the syntax. To this end we transform the environment-based abstract machine into the substitution-based abstract machine displayed in Figure 8. The transformation is standard, except that we also need to embed evaluation contexts in the syntax; hence the substitution-based machine operates on terms where "quoted" (in the sense of Lisp) contexts can occur. (If it were not for shift and reset, C 2 and its transitions could be omitted and the abstract machine would reduce to the CK machine [38].) We write t{v/x } to denote the result of the usual capture-avoiding substitution of the value v for x in t.
Formally, the relationship between the two machines is expressed with the following simulation theorem, where evaluation with the substitution-based abstract machine is captured by the partial function eval s , defined analogously to eval e .
Proof. We extend the translation function T to meta-contexts and configurations, in the expected way, e.g., Then it is straightforward to show that the two abstract machines operate in lock step with respect to the translation. Hence, for any program t, both machines diverge or they both stop (after the same number of transitions) with the values v and T (v), respectively.
We now proceed to analyze the transitions of the machine displayed in Figure 8. We can think of a configuration t, C 1 , C 2 eval as the following decomposition of the initial term into a meta-context C 2 , a context C 1 , and an intermediate term t: where # separates the context and the meta-context. Each transition performs either a reduction, or a decomposition in search of the next redex. Let us recall that a decomposition is performed when both sides of a transition are partitions of the same term; in that case, depending on the structure of the decomposition C 2 # C 1 [t], a subpart of the term is chosen to be evaluated next, and the contexts are updated accordingly. We also observe that evaltransitions follow the structure of t, cont 1 -transitions follow the structure of C 1 when the term has been reduced to a value, and cont 2 -transitions follow the structure of C 2 when a value in the empty context has been reached.
Next we specify all the components of the reduction semantics based on the analysis of the abstract machine.

A reduction semantics
A reduction semantics provides a reduction relation on expressions by defining values, evaluation contexts, and redexes [35,37,38,79]. In the present case, • the values are already specified in the (substitution-based) abstract machine: • the evaluation contexts and meta-contexts are already specified in the abstract machine, as the data-type part of defunctionalized continuations; • we can read the redexes off the transitions of the abstract machine: Based on the distinction between decomposition and reduction, we single out the following reduction rules from the transitions of the machine: (β λ ) is the usual call-by-value β-reduction; we have renamed it to indicate that the applied term is a λ-abstraction, since we can also apply a captured context, as in (β ctx ). (S λ ) is plausibly symmetric to (β λ ) -it can be seen as an application of the abstraction λk .t to the current context. Moreover, (β ctx ) can be seen as performing both a reduction and a decomposition: it is a reduction because an application of a context with a hole to a value is reduced to the value plugged into the hole; and it is a decomposition because it changes the meta-context, as if the application were enclosed in a reset. Finally, (val) makes it possible to pass the boundary of a context when the term inside this context has been reduced to a value.
The β ctx -rule and the S λ -rule give a justification for representing a captured context C 1 as a term λx . C 1 [x ] , as found in other studies of shift and reset [53,54,62]. In particular, the need for delimiting the captured context is a consequence of the β ctx -rule.
Finally, we can read the decomposition function off the transitions of the abstract machine: In the remaining cases either a value or a redex has been found: An inverse of the decompose function, traditionally called plug, reconstructs a term from its decomposition: In order to talk about unique decomposition, we need to define the set of potential redexes (i.e., the disjoint union of actual redexes and stuck redexes). The grammar of potential redexes reads as follows:

Lemma 1 (Unique decomposition). A program t is either a value v or there exist a unique
context C 1 , a unique meta-context C 2 and a potential redex p such that t = plug (C 2 # C 1 [p]). In the former case decompose (t) = • # [v] and in the latter case either decompose (t) = C 2 # C 1 [p] if p is an actual redex, or decompose (t) is undefined.
Proof. The first part follows by induction on the structure of t. The second part follows from the equation decompose (plug (C 2 # C 1 [r])) = C 2 # C 1 [r] which holds for all C 2 , C 1 and r.
It is evident that evaluating a program either using the derived reduction rules or using the substitution-based abstract machine yields the same result. Proof. When evaluating with the abstract machine, each contraction is followed by decomposing the contractum in the current context and meta-context. When evaluating with the reduction rules, however, each contraction is followed by plugging the contractum and decomposing the resulting term. Therefore, the theorem follows from the equation which holds for any C 2 , C 1 and t.
We have verified that using refocusing [30], one can go from this reduction semantics to the abstract machine of Figure 8

Beyond CPS
Alternatively to using the meta-context to compose delimited continuations, as in Figure 7, we could compose them by concatenating their representation. Such a concatenation function is defined as follows: (The second clause would read (ARG(t, C 1 )) C 1 = ARG(t, C 1 C 1 ) for the contexts of Figure 8.) Then, in Figures 7 and 8, we could replace the transition by the following one: This replacement changes the control effect of shift to that of Felleisen et al.'s F operator [36]. Furthermore, the modified abstract machine is in structural correspondence with Felleisen et al.'s abstract machine for F and # [36,40]. This representation of control (as a list of 'stack frames') and this implementation of composing delimited continuations (by concatenating these lists) are at the heart of virtually all non-CPS-based accounts of delimited control. However, the modified environment-based abstract machine does not correspond to a defunctionalized continuation-passing evaluator because it is not in the range of defunctionalization [29] since the first-order representation of functions should have a single point of consumption. Here, the constructors of contexts are not solely consumed by the cont 1 transitions of the abstract machine as in Figures 7 and 8, but also by . Therefore, the abstract machine that uses is not in the range of Reynolds's defunctionalization and it thus does not immediately correspond to a higher-order, continuation-passing evaluator. In that sense, control operators using go beyond CPS.
Elsewhere [18], we have rephrased the modified abstract machine to put it in defunctionalized form, and we have exhibited the corresponding higher-order evaluator and the corresponding continuation-passing style. This dynamic CPS is not just plain CPS but is a form of continuation+state-passing style where the threaded state is a list of intermediate delimited continuations. Unexpectedly, it is also in structural correspondence with the architecture for delimited control recently proposed by Dybvig, Peyton Jones, and Sabry on other operational grounds [34].
In any case, and irrespectively of any new dynamic CPS and any new architecture for delimited control, there seems to be remarkably few examples that actually illustrate the expressive power of dynamic delimited continuations. We have recently presented one, breadth-first traversal [17], and we present another one below.
The two following functions traverse a given list and return another list. The recursive call to visit is abstracted into a delimited continuation, which is applied to the tail of the list: On the left, foo uses S and on the right, bar uses F; for the rest, the two definitions are identical. Given an input list, foo copies it and bar reverses it.
To explain this difference and to account for the extended source language, we need to expand the grammar of evaluation contexts, e.g., with a production to account for calls to the list constructor: Similarly, we need to expand the definition of concatenation as follows: Here is a trace of the two computations in the form of the calls to and returns from visit for the input list 1 :: 2 :: nil : foo: Every time the captured continuation is resumed, its representation is kept separate from the current context. The meta-context therefore grows whereas the captured context solely consists of FUN(visit , [ ]) throughout (writing visit in the context for simplicity):

Summary and conclusion
We have presented the original evaluator for the λ-calculus with shift and reset; this evaluator uses two layers of continuations. From this call-by-value evaluator we have derived two abstract machines, an environment-based one and a substitution-based one; each of these machines uses two layers of evaluation contexts. Based on the substitution-based machine we have constructed a reduction semantics for the λ-calculus with shift and reset; this reduction semantics, by construction, is sound with respect to CPS.

From evaluator to reduction semantics for the CPS hierarchy
We construct a reduction semantics for the call-by-value λ-calculus extended with shift n and reset n . As in Section 4, we go from an evaluator to an environment-based abstract machine, and from a substitution-based abstract machine to a reduction semantics. Because of the regularity of CPS, the results can be generalized from level 1 to higher levels without repeating the actual construction, based only on the original specification of the hierarchy [27].
In particular, the proofs of the theorems generalize straightforwardly from level 1.

22
The evaluator uses n+1 layers of continuations. In the five first clauses (literal, variable, λabstraction, function application, and application of the successor function), the continuations k 2 , . . . , k n+1 are passive: if the evaluator were curried, they could be eta-reduced. In the clauses defining shift i and reset i , the continuations k i+2 , . . . , k n+1 are also passive. Each pair of control operators is indexed by the corresponding level in the hierarchy: reset i is used to "push" each successive continuation up to level i onto level i + 1 and to reinitialize them with θ 1 , . . . , θ i , which are the successive CPS counterparts of the identity function; shift i is used to abstract control up to level i into a delimited continuation and to reinitialize the successive continuations up to level i with θ 1 , . . . , θ i .
Applying a delimited continuation that was abstracted up to level i "pushes" each successive continuation up to level i onto level i + 1 and restores the successive continuations that were captured in a delimited continuation. When such a delimited continuation completes, and when an expression delimited by reset i completes, the successive continuations that were pushed onto level i + 1 are "popped" back into place and the computation proceeds.

An environment-based abstract machine
Defunctionalizing the evaluator of Figures 9 and 10 yields the environment-based abstract machine displayed in Figures 11 and 12. If n = 1, it coincides with the abstract machine displayed in Figure 7.
The abstract machine consists of n + 2 sets of transitions: eval for interpreting terms and cont 1 , . . . , cont n+1 for interpreting the successive defunctionalized continuations. The set of possible values includes integers, closures and captured contexts.
This abstract machine is an extension of the abstract machine displayed in Figure 7 with n + 1 contexts instead of 2 and the corresponding transitions for shift i and reset i . Each meta i+1 -context intervenes to process reset i expressions and to apply captured continuations. Otherwise, the successive contexts are passively threaded to process literals, variables, λabstractions, function applications, and applications of the successor function.
Given an environment e and a series of successive contexts, a reset i expression t i is processed by evaluating t with the same environment e, i empty contexts, and a meta i+1context over which all the intermediate contexts have been pushed on.
• Evaluation contexts (2 ≤ i ≤ n + 1):   , C 1 , C 2 , . . ., C n+1 eval ⇒ C 1 , m, C 2 , . . ., C n+1 cont 1 x , e, C 1 ,  Given an environment e and a series of successive contexts, a shift expression S i k.t is processed by evaluating t with an extension of e where k denotes a composition of the i surrounding contexts, i empty contexts, and the remaining outer contexts. Applying a captured context is achieved by pushing all the current contexts on the next outer context, restoring the composition of the captured contexts, and continuing with them. Resuming a composition of captured contexts is achieved by popping them off the next outer context and continuing with them.
In order to relate the resulting abstract machine to the evaluator, we define a partial function eval e n mapping a term t to a value v whenever the machine for level n, started with t, stops with v. The correctness of the machine with respect to the evaluator is ensured by the following theorem:

A substitution-based abstract machine
In the same fashion as in Section 4.3, we construct the substitution-based abstract machine corresponding to the environment-based abstract machine of Section 5.2. The result is displayed in Figures 13 and 14. If n = 1, it coincides with the abstract machine displayed in Figure 8.
The nth level contains n + 1 evaluation contexts and each context C i can be viewed as a stack of non-empty contexts C i−1 . Terms are decomposed as where each # i represents a context delimiter of level i. All the control operators that occur at the jth level (with j < n) of the hierarchy do not use the contexts j + 2, . . . , n + 1. The functions decompose and its inverse plug can be read off the machine, as for level 1.
The transitions of the machine for level j are "embedded" in the machine for level j + 1; the extra components are threaded but not used.
We define a partial function eval s n capturing the evaluation by the substitution-based abstract machine for an arbitrary level n, analogously to the definition of eval e n . Now we can • Terms and values (1 ≤ i ≤ n): t : • Evaluation contexts (2 ≤ i ≤ n + 1):

A reduction semantics
Along the same lines as in Section 4.4, we construct the reduction semantics for the CPS hierarchy based on the abstract machine of Figures 13 and 14. For an arbitrary level n we obtain the following set of reduction rules, for all 1 ≤ i ≤ n; they define the actual redexes: Each level contains all the reductions from lower levels, and these reductions are compatible with additional layers of evaluation contexts. In particular, at level 0 there are only δand β λ -reductions.
The values and evaluation contexts are already specified in the abstract machine. Moreover, the potential redexes are defined according to the following grammar: Lemma 2 (Unique decomposition for level n). A program t is either a value or there exists a unique sequence of contexts C 1 , . . . , C n+1 and a potential redex p n such that t = plug (C n+1 # n · · · # 1 C 1 [p n ]).
Evaluating a term using either the derived reduction rules or the substitution-based abstract machine from Section 5.3 yields the same result:

Beyond CPS
As in Section 4.5, one can define a concatenation function over contexts and use it to implement composable continuations in the CPS hierarchy. Again the modified environment-based abstract machine does not immediately correspond to a defunctionalized continuation-passing evaluator. Such control operators go beyond traditional CPS.

Summary and conclusion
We have generalized the results presented in Section 4 from level 1 to the whole CPS hierarchy of control operators shift n and reset n . Starting from the original evaluator for the λ-calculus with shift n and reset n that uses n + 1 layers of continuations, we have derived two abstract machines, an environment-based one and a substitution-based one; each of these machines use n + 1 layers of evaluation contexts. Based on the substitution-based machine we have obtained a reduction semantics for the λ-calculus extended with shift n and reset n which, by construction, is sound with respect to CPS.

Programming in the CPS hierarchy
To finish, we present new examples of programming in the CPS hierarchy. The examples are normalization functions. In Sections 6.1 and 6.2, we first describe normalization by evaluation and we present the simple example of the free monoid. In Section 6.3, we present a function mapping a proposition into its disjunctive normal form; this normalization function uses delimited continuations. In Section 6.4, we generalize the normalization functions of Sections 6.2 and 6.3 to a hierarchical language of units and products, and we express the corresponding normalization function in the CPS hierarchy.

Normalization by evaluation
Normalization by evaluation is a 'reduction-free' approach to normalizing terms. Instead of reducing a term to its normal form, one evaluates this term into a non-standard model and reifies its denotation into its normal form [33]: eval : term → value reify : value → term nf normalize : term → term nf normalize = reify • eval Normalization by evaluation has been developed in intuitionistic type theory [19,59], proof theory [12,13], category theory [4], and partial evaluation [21,22], where it has emerged as a new field of application for delimited continuations [9,22,33,43,46,49,74].

The free monoid
A source term in the free monoid is either a variable, the unit element, or the product of two terms: term The product is associative and the unit element is neutral. These properties justify the following conversion rules: We aim (for example) for list-like flat normal forms: In a reduction-based approach to normalization, one would orient the conversion rules into reduction rules and one would apply these reduction rules until a normal form is obtained: In a reduction-free approach to normalization, one defines a normalization function as the composition of a non-standard evaluation function and a reification function. Let us state such a normalization function.
The non-standard domain of values is the transformer The evaluation function is defined by induction over the syntax of source terms, and the reification function inverts it: In effect, eval is a mapping from the source monoid to the monoid of transformers (unit is mapped to unit and products are mapped to products) and the normalization function hinges on the built-in associativity of function composition. Dybjer et al. have studied its theoretical content [14,19,56]. From a (functional) programming standpoint, the reductionbased approach amounts to flattening a tree iteratively by reordering it, and the reduction-free approach amounts to flattening a tree with an accumulator.

A language of propositions
A source term, i.e., a proposition, is either a variable, a literal (true or false), a conjunction, or a disjunction: Conjunction and disjunction are associative and distribute over each other; true is neutral for conjunction and absorbant for disjunction; and false is neutral for disjunction and absorbant for conjunction. We aim (for example) for list-like disjunctive normal forms: Our normalization function is the result of composing a non-standard evaluation function and a reification function. We state them below without proof.

Given the domains of transformers
the non-standard domain of values is ans 1 , where The evaluation function is defined by induction over the syntax of source terms, and the reification function inverts it: This normalization function uses a continuation k, an accumulator d to flatten disjunctions, and another one c to flatten conjunctions. The continuation is delimited: the three first clauses of eval 0 are in CPS; in the fourth, k is discarded (accounting for the fact that false is absorbant for conjunction); and in the last, k is duplicated and used in non-tail position (achieving the distribution of conjunctions over disjunctions). The continuation and the accumulators are initialized in the definition of reify 0 .
Uncurrying the continuation and mapping eval 0 and reify 0 back to direct style yield the following definition, which lives at level 1 of the CPS hierarchy: The three first clauses of eval 1 are in direct style; the two others abstract control with shift. In the fourth clause, the context is discarded; and in the last clause, the context is duplicated and composed. The context and the accumulators are initialized in the definition of reify 1 .
This direct-style version makes it even more clear than the CPS version that the accumulator for the disjunctions in normal form is a threaded state. A continuation-based, state-based version (or better, a monad-based one) can therefore be written-but it is out of scope here.

A hierarchical language of units and products
We consider a generalization of propositional logic where a source term is either a variable, a unit in a hierarchy of units, or a product in a hierarchy of products: All the products are associative. All units are neutral for products with the same index.
The free monoid: The language corresponds to that of the free monoid if n = 1, as in Section 6.2.

Boolean logic:
The language corresponds to that of propositions if n = 2, as in Section 6.3: ε 1 is true, 1 is ∧, ε 2 is false, and 2 is ∨.

Multi-valued logic:
In general, for each n > 2 we can consider a suitable n-valued logic [45]; for example, in case n = 4, the language corresponds to that of Belnap's bilattice FOUR [11]. It is also possible to modify the normalization function to work for less regular logical structures (e.g., other bilattices).

Monads:
In general, the language corresponds to that of layered monads [60]: each unit element is the unit of the corresponding monad, and each product is the 'bind' of the corresponding monad. In practice, layered monads are collapsed into one for programming consumption [42], but prior to this collapse, all the individual monad operations coexist in the computational soup.
In the remainder of this section, we assume that all the products, besides being associative, distribute over each other, and that all units, besides being neutral for products with the same index, are absorbant for products with other indices. We aim (for example) for a generalization of disjunctive normal forms: term nf t ::= t n term nf n t n ::= ε nf n | t n−1 nf n t n . . . For presentational reasons, in the remainder of this section we arbitrarily fix n to be 5.
Our normalization function is the result of composing a non-standard evaluation function and a reification function. We state them below without proof. Given the domains of transformers The evaluation function is defined by induction over the syntax of source terms, and the reification function inverts it: This normalization function uses four delimited continuations k 1 , k 2 , k 3 , k 4 and five accumulators t 1 , t 2 , t 3 , t 4 , t 5 to flatten each of the successive products. In the clause of each ε i , the continuations k 1 , . . . , k i−1 are discarded, accounting for the fact that ε i is absorbant for 1 , . . . , i−1 , and the identity function is passed to k i , accounting for the fact that ε i is neutral for i . In the clause of each i+1 , the continuations k 1 , . . . , k i are duplicated and used in non-tail position, achieving the distribution of i+1 over 1 , . . . , i . The continuations and the accumulators are initialized in the definition of reify 0 . This normalization function lives at level 0 of the CPS hierarchy, but we can express it at a higher level using shift and reset. For example, uncurrying k 3 and k 4 and mapping eval 0 and reify 0 back to direct style twice yield the following intermediate definition, which lives at level 2: Whereas eval 0 had four layered continuations, eval 2 has only two layered continuations since it has been mapped back to direct style twice. Where eval 0 accesses k 3 as one of its parameters, eval 2 abstracts the first layer of control with shift 1 , and where eval 0 accesses k 4 as one of its parameters, eval 2 abstracts the first and the second layer of control with shift 2 .

A note about efficiency
We have implemented all the definitions of Section 6.4 as well as the intermediate versions eval 1 and eval 3 , using Standard ML of New Jersey [31]. We have also implemented hierarchical normalization functions for other values than 5.
For high products (i.e., in Section 6.4, for source terms using 3 and 4 ), the normalization function living at level 0 of the CPS hierarchy is the most efficient one. On the other hand, for low products (i.e., in Section 6.4, for source terms using 1 and 2 ), the normalization functions living at a higher level of the CPS hierarchy are the most efficient ones. These relative efficiencies are explained in terms of resources: • Accessing to a continuation as an explicit parameter is more efficient than accessing to it through a control operator.
• On the other hand, the restriction of eval 4 to source terms that only use ε 1 and 1 is in direct style, whereas the corresponding restrictions of eval 2 and eval 0 pass a number of extra parameters. These extra parameters penalize performance.
The better performance of programs in the CPS hierarchy has already been reported for level 1 in the context of continuation-based partial evaluation [58], and it has been reported for a similar "pay as you go" reason: a program that abstracts control relatively rarely is run more efficiently in direct style with a control operator rather than in continuation-passing style.

Summary and conclusion
We have illustrated the CPS hierarchy with an application of normalization by evaluation that naturally involves successive layers of continuations and that demonstrates the expressive power of shift n and reset n . The application also suggests alternative control operators that would fit better its continuation-based programming pattern. For example, instead of representing a delimited continuation as a function and apply it as such, we could represent it as a continuation and apply it with a throw operator as in MacLisp and Standard ML of New Jersey. For another example, instead of throwing a value to a continuation, we could specify the continuation of a computation, e.g., with a reflect i special form. For a third example, instead of abstracting control up to a layer n, we could give access to each of the successive layers up to n, e.g., with a L n operator. Then instead of eval 4 (t 4 t ) t 5 = S 1 k 1 .S 2 k 2 .S 3 k 3 .let (f 4 , t 5 ) = k 3 k 2 k 1 (eval 4 t t 5 ) 1 2 3 in let (f 4 , t 5 ) = k 3 k 2 k 1 (eval 4 t t 5 ) 1 2 3 in (f 4 • f 4 , t 5 ) one could write eval 4 (t 4 t ) t 5 = L 3 (k 1 , k 2 , k 3 ).let (f 4 , t 5 ) = reflect 3 (eval 4 t t 5 , k 1 , k 2 , k 3 ) in let (f 4 , t 5 ) = reflect 3 (eval 4 t t 5 , k 1 , k 2 , k 3 ) in (f 4 • f 4 , t 5 ).
Such alternative control operators can be more convenient to use, while being compatible with CPS.

Conclusion and issues
We have used CPS as a guideline to establish an operational foundation for delimited continuations. Starting from a call-by-value evaluator for λ-terms with shift and reset, we have mechanically derived the corresponding abstract machine. From this abstract machine, it is straightforward to obtain a reduction semantics of delimited control that, by construction, is compatible with CPS-both for one-step reduction and for evaluation. These results can also be established without the guideline of CPS, but less easily. The whole approach generalizes straightforwardly to account for the shift n and reset n family of delimited-control operators and more generally for any control operators that are compatible with CPS. These results would be non-trivial to establish without the guideline of CPS.
Defunctionalization provides a key for connecting continuation-passing style and operational intuitions about control. Indeed most of the time, control stacks and evaluation contexts are the defunctionalized continuations of an evaluator. Defunctionalization also provides a key for identifying where operational intuitions about control go beyond CPS (see Section 4.5). We do not know whether CPS is the ultimate answer, but the present work shows yet another example of its usefulness. It is like nothing can go wrong with CPS.