One Step at a Time
Abstract
Bigstep and smallstep are two popular flavors of operational semantics. Bigstep is often seen as a more natural transcription of informal descriptions, as well as being more convenient for some applications such as interpreter generation or optimization verification. Smallstep allows reasoning about nonterminating computations, concurrency and interactions. It is also generally preferred for reasoning about type systems. Instead of having to manually specify equivalent semantics in both styles for different applications, it would be useful to choose one and derive the other in a systematic or, preferably, automatic way.
Transformations of smallstep semantics into bigstep have been investigated in various forms by Danvy and others. However, it appears that a corresponding transformation from bigstep to smallstep semantics has not had the same attention. We present a fully automated transformation that maps bigstep evaluators written in direct style to their smallstep counterparts. Many of the steps in the transformation, which include CPSconversion, defunctionalisation, and various continuation manipulations, mirror those used by Danvy and his coauthors. For many standard languages, including those with either callbyvalue or callbyneed and those with state, the transformation produces smallstep semantics that are close in style to handwritten ones. We evaluate the applicability and correctness of the approach on 20 languages with a range of features.
Keywords
Structural operational semantics Bigstep semantics Smallstep semantics Interpreters Transformation Continuationpassing style Functional programming1 Introduction
Operational semantics allow language designers to precisely and concisely specify the meaning of programs. Such semantics support formal type soundness proofs [29], give rise (sometimes automatically) to simple interpreters [15, 27] and debuggers [14], and document the correct behavior for compilers. There are two popular approaches for defining operational semantics: bigstep and smallstep. Bigstep semantics (also referred to as natural or evaluation semantics) relate initial program configurations directly to final results in one “big” evaluation step. In contrast, smallstep semantics relate intermediate configurations consisting of the term currently being evaluated and auxiliary information. The initial configuration corresponds to the entire program, and the final result, if there is one, can be obtained by taking the transitivereflexive closure of the smallstep relation. Thus, computation progresses as a series of “small steps.”
The two styles have different strengths and weaknesses, making them suitable for different purposes. For example, bigstep semantics naturally correspond to definitional interpreters [23], meaning many bigstep semantics can essentially be transliterated into a reasonably efficient interpreter in a functional language. Bigstep semantics are also more convenient for verifying program optimizations and compilation – using bigstep, semantic preservation can be verified (for terminating programs) by induction on the derivation [20, 22].
In contrast, smallstep semantics are often better suited for stepping through the evaluation of an example program, and for devising a type system and proving its soundness via the classic syntactic method using progress and preservation proofs [29]. As a result, researchers sometimes develop multiple semantic specifications and then argue for their equivalence [3, 20, 21]. In an ideal situation, the specifier writes down a single specification and then derives the others.
Approaches to deriving bigstep semantics from a smallstep variant have been investigated on multiple occasions, starting from semantics specified as either interpreters or rules [4, 7, 10, 12, 13]. An obvious question is: what about the reverse direction?
This paper presents a systematic, mechanised transformation from a bigstep interpreter into its smallstep counterpart. The overall transformation consists of multiple stages performed on an interpreter written in a functional programming language. For the most part, the individual transformations are well known. The key steps in this transformation are to explicitly represent control flow as continuations, to defunctionalise these continuations to obtain a datatype of reified continuations, to “tear off” recursive calls to the interpreter, and then to return the reified continuations, which represent the rest of the computation. This process effectively produces a stepping function. The remaining work consists of finding translations from the reified continuations to equivalent terms in the source language. If such a term cannot be found, we introduce a new term constructor. These new constructors correspond to the intermediate auxiliary forms commonly found in handwritten smallstep definitions.
We define the transformations on our evaluator definition language – an extension of \(\lambda \)calculus with callbyvalue semantics. The language is untyped and, crucially, includes tagged values (variants) and a case analysis construct for building and analysing object language terms. Our algorithm takes as input a bigstep interpreter written in this language in the usual style: a main function performing case analysis on a toplevel term constructor and recursively calling itself or auxiliary functions. As output, we return the resulting smallstep interpreter which we can “prettyprint” as a set of smallstep rules in the usual style. Hence our algorithm provides a fully automated path from a restricted class of bigstep semantic specifications written as interpreters to corresponding smallstep versions.
To evaluate our algorithm, we have applied it to 20 different languages with various features, including languages based on callbyname and callbyvalue \(\lambda \)calculi, as well as a core imperative language. We extend these base languages with conditionals, loops, and exceptions.

We present a multistage, automated transformation that maps any deterministic bigstep evaluator into a smallstep counterpart. Section 2 gives an overview of this process. Each stage in the transformation is performed on our evaluator definition language – an extended callbyvalue \(\lambda \)calculus. Each stage in the transformation is familiar and principled. Section 4 gives a detailed description.

We have implemented the transformation process in Haskell and evaluate it on a suite of 20 representative languages in Section 5. We argue that the resulting smallstep evaluation rules closely mirror what one would expect from a manually written smallstep specification.

We observe that the same process with minimal modifications can be used to transform a bigstep semantics into its prettybigstep [6] counterpart.
2 Overview
We will now give a series of interpreters to illustrate the transformation process. We formally define the syntax of the metalanguage in which we write these interpreters in Section 3, but we believe for readers familiar with functional programming the language is intuitive enough to not require a full explanation at this point. Open image in new window highlights (often small) changes to subsequent interpreters.
BigStep Evaluator. We start with an interpreter corresponding directly to the bigstep semantics given in Fig. 2. We represent environments as functions – the empty environment returns an error for any variable. The body of the Open image in new window function consists of a pattern match on the toplevel language term. Function abstractions are evaluated to closures by packaging them with the current environment. The only term that requires recursive calls to Open image in new window is application: both its arguments are evaluated in the current environment, and then its first argument is patternmatched against a closure, the body of which is then evaluated to a value in an extended environment using a third recursive call to Open image in new window .
Convert Continuations into Terms. At this point, we have a stepping function that returns either a term or a continuation, but we want a function returning only terms. The most straightforward approach to achieving this goal would be to introduce a term constructor for each defunctionalized continuation constructor. However, many of these continuation constructors can be trivially expressed using constructors already present in the object language. We want to avoid introducing redundant terms, so we aim to reuse existing constructors as much as possible. In our example we observe that Open image in new window corresponds to Open image in new window , while Open image in new window to Open image in new window . We might also observe that Open image in new window would correspond to Open image in new window if Open image in new window . Our current implementation doesn’t handle such cases, however, and so we introduce Open image in new window as a new term constructor.
3 BigStep Specifications
We define our transformations on an untyped extended \(\lambda \)calculus with callbyvalue semantics that allows the straightforward definition of big and smallstep interpreters. We call this language an evaluator definition language (EDL).
3.1 Evaluator Definition Language
Table 1 gives the syntax of EDL. We choose to restrict ourselves to Anormal form, which greatly simplifies our partial CPS conversion without compromising readability. Our language has the usual callbyvalue semantics, with arguments being evaluated lefttoright. All of the examples of the previous section were written in this language.
Our language has 3 forms of letbinding constructs: the usual (optionally recursive) Open image in new window , a letconstruct for evaluator definition, and a letconstruct for defining continuations. The behavior of all three constructs is the same, however, we treat them differently during the transformations. The Open image in new window construct also comes with the additional static restriction that it may appear only once (i.e., there can be only one evaluator). The Open image in new window and Open image in new window forms are recursive by default, while Open image in new window has an optional Open image in new window specifier to create a recursive binding. For simplicity, our language does not offer implicit mutual recursion, so mutual recursion has to be made explicit by inserting additional arguments. We do this when we generate the Open image in new window function during defunctionalization.
Syntax of the evaluator definition language.
4 Transformation Steps
In this section, we formally define each of the transformation steps informally described in Section 2. For each transformation function, we list only the most relevant cases; the remaining cases trivially recurse on the Anormal form (ANF) abstract syntax. We annotate functions with E, \( CE \), and \( AE \) to indicate the corresponding ANF syntactic classes. We omit annotations when a function only operates on a single syntactic class. For readability, we annotate metavariables to hint at their intended use – \(\rho \) stands for readonly entities (such as environments), whereas \(\sigma \) stands for readwrite or “statelike” entities of a configuration (e.g., stores or exception states). These can be mixed with our notation for syntactic lists, so, for example, \(\vec {x}^\sigma \) is a sequence of variables referring to statelike entities, while \(\vec {ae}^\rho \) is a sequence of aexpressions corresponding to readonly entities.
4.1 CPS Conversion

The evaluator name is globally unique.

The evaluator is never applied partially.

All bound variables are distinct.
4.2 Generalization of Continuations

Open image in new window is the unique use site of the continuation k in expression e, that is, the \( CExpr \) where Open image in new window is applied with k as its continuation; and

\(\hat{x}\) is a fresh variable associated with x – it stands for “a term corresponding to (the value) x”.
Following the CPS conversion, each named continuation is applied exactly once in e, so Open image in new window is total and returns the continuation’s unique use site. Moreover, because the continuation was originally defined and letbound at that use site, all free variables in Open image in new window are also free in the definition of k.
4.3 Argument Lifting in Continuations
In the next phase, we partially lift free variables in continuations to make them explicit arguments. We perform a selective lifting in that we avoid lifting nonterm arguments to the evaluation function. These arguments represent entities that parameterize the evaluation of a term. If an entity is modified during evaluation, the modified entity variable gets lifted. In the running example of Section 2, such a lifting occurred for \( kclo _1\).

\(\varXi ' = \varXi \cup \{ k \}\)

\(\varDelta ' = \varDelta [k \mapsto (x_1, \ldots , x_n)]\)
Our lifting function is a restricted version of a standard argumentlifting algorithm [19]. The first restriction is that we do not lift all free variables, since we do not aim to float and lift the continuations to the toplevel of the program, only to the toplevel of the evaluation function. The other difference is that we can use a simpler way to compute the set of lifted parameters due to the absence of mutual recursion between continuations. The correctness of this can be proved using the approach of Fischbach [16].
4.4 Continuations Switch Control Directly
4.5 Defunctionalization
4.6 Remove Selfrecursive TailCalls
4.7 Convert Continuations to Terms
If, starting from an input term \(c(\vec {x})\), an invocation of Open image in new window on a continuation term \(c^\textsc {k}(\vec {ae}_k)\) is reached, and if, after instantiating the variables in the input term \(c(\vec {ae})\), the sets of their free variables are equal, then we can introduce a translation from \(c^\textsc {k}(\vec {ae}_k)\) into \(c(\vec {ae})\). If such a direct path is not found, the \(c^\textsc {k}\) will become a new term constructor in the language and a case in Open image in new window is introduced such that the above equation is satisfied.
4.8 Inlining, Simplification and Conversion to Direct Style
4.9 Removing Vacuous Continuations
4.10 Detour: Generating PrettyBigStep Semantics
As we can see, the evaluation of Open image in new window now proceeds through two intermediate constructs, Open image in new window , which correspond to continuations introduced in the CPS conversion. The evaluation of Open image in new window starts by evaluating \(e_1\) to \(v_1\). Then Open image in new window is responsible for evaluating \(e_2\) to \(v_2\). Finally, Open image in new window evaluates the closure body just as the third premise of the original rule for Open image in new window . Save for different order of arguments, the resulting intermediate constructs and their rules are identical to Charguéraud’s examples.
4.11 PrettyPrinting
For the purpose of presenting and studying the original and transformed semantics, we add a final prettyprinting phase. This amounts to generating inference rules corresponding to the control flow in the interpreter. This prettyprinting stage can be applied to both the bigstep and smallstep interpreters and was used to generate many of the rules in this paper, as well as for generating the appendix of the full version of this paper [1].
4.12 Correctness
A correctness proof for the full pipeline is not part of our current work. However, several of these steps (partial CPS conversion, partial argument lifting, defunctionalization, conversion to direct style) are instances of wellestablished techniques. In other cases, such as generalization of continuations (Section 4.2) and removal of selfrecursive tailcalls (Section 4.6), we have informal proofs using equational reasoning [1]. The proof for tailcall removal is currently restricted to compositional interpreters.
5 Evaluation
Overview of transformed example languages. Input is a given bigstep interpreter and our transformations produce a smallstep counterpart as output automatically. “Prems” columns only list structural premises: those that check for a big or small step. Unless otherwise stated, environments are used to give meaning to variables and they are represented as functions.
For our case studies, we have used callbyvalue and callbyname \(\lambda \)calculi, and a simple imperative language as base languages and extended them with some common features. Overall, the smallstep specifications (as well as the corresponding interpreters) resulting from our transformation are very similar to ones we could find in the literature. The differences are either well justified—for example, by different handling of value terms—or they are due to new term constructors which could be potentially eliminated by a more powerful translation.
We evaluated the correctness of our transformation experimentally, by comparing runs of the original bigstep and the transformed smallstep interpreters, as well as by inspecting the interpreters themselves. In a few cases, we proved the transformation correct by transcribing the input and output interpreters in Coq (as an evaluation relation coupled with a proof of determinism) and proving them equivalent. From the examples in Table 2, we have done so for “Callbyvalue”, “Exceptions as state”, and a simplified version of “CBV, exceptions as state”.
We make a few observations about the resulting semantics here.
Our current, straightforward way of deriving term–continuation equivalents is not capable of finding these equivalences. In future work, we want to explore external tools, such as SMT solvers, to facilitate searching for translations from continuations to terms. This search could be possibly limited to a specific term depth.
Since we expect the input semantics to be deterministic and the propagation of exceptions in the resulting smallstep follows the original bigstep semantics, this “slow” propagation is not a problem, even if it does not take advantage of “fast” propagation via labels or state. A possible solution we are considering for future work is to let the user flag values in the bigstep semantics and translate such values as labels on arrows or a state change to allow propagating them in a single step.
Using state to propagate exceptions is mentioned in connection with smallstep SOS in [4]. While this approach has the potential advantage of manifesting the currently raised exception immediately at the toplevel, it also poses a problem of locality. If an exception is reinserted into the configuration, it might become decoupled from the original site. This can result, for example, in the wrong handler catching the exception in a following step. Our transformation deals with this style of exceptions naturally by preserving more continuations in the final interpreter. After being raised, an exception is inserted into the state and propagated to toplevel by congruence rules. However, it will only be caught after the corresponding subterm has been evaluated, or rather, a value has been propagated upwards to signal a completed computation. This behavior corresponds to exception handling in bigstep rules, only it is spread out over multiple steps. Continuations are kept in the final language to correspond to stages of computation and thus, to preserve the locality of a raised exception. A handler will only handle an exception once the raising subterm has become a value. Hence, the exception will be intercepted by the innermost handler – even if the exception is visible at the toplevel of a step.
Based on our experiments, the exceptionasstate handling in the generated smallstep interpreters is a truthful unfolding of the bigstep evaluation process. This is further supported by our adhoc proofs of equivalence between input and output interpreters. However, the generated semantics suffers from a blowup in the number of rules and moves away from the usual smallstep propagation and exception handling in congruence rules. We see this as a shortcoming of the transformation. To overcome this, we briefly experimented with a casefloating stage, which would result in catching exceptions in the congruence cases of continuations. Using such transformation, the resulting interpreter would more closely mirror the standard smallstep treatment of exceptions as signals. However, the conditions when this transformations should be triggered need to be considered carefully and we leave this for future work.
6 Related Work
In their short paper [18], the authors propose a direct syntactic way of deriving smallstep rules from bigstep ones. Unlike our approach, based on manipulating control flow in an interpreter, their transformation applies to a set of inference rules. While axioms are copied over directly, for conditional rules a stack is added to the configuration to keep track of evaluation. For each conditional bigstep rule, an auxiliary construct and 4 smallstep rules are generated. Results of “premise computations” are accumulated and sideconditions are only discharged at the end of such a computation sequence. For this reason, we can view the resulting semantics more as a “leap” semantics, which makes it less suitable for a semanticsbased interpreter or debugger. A further disadvantage is that the resulting semantics is far removed from a typical smallstep specification with a higher potential for blowup as 4 rules are introduced for each conditional rule. On the other hand, the delayed unification of metavariables and discharging of sideconditions potentially makes the transformation applicable to a wider array of languages, including those where control flow is not as explicit.
In [2], the author explores an approach to constructing abstract machines from bigstep (natural) specifications. It applies to a class of bigstep specifications called Lattributed bigstep semantics, which allows for sufficiently interesting languages. The extracted abstract machines use a stack of evaluation contexts to keep track of the stages of computations. In contrast, our transformed interpreters rebuild the context via congruence rules in each step. While this is less efficient as a computation strategy, the intermediate results of the computation are visible in the context of the original program, in line with usual SOS specifications.
A significant body of work has been developed on transformations that take a form of smallstep semantics (usually an interpreter) and produce a bigstepstyle interpreter. The relation between semantic specifications, interpreters and abstract machines has been thoroughly investigated, mainly in the context of reduction semantics [10, 11, 12, 13, 26]. In particular, our work was inspired by and is based on Danvy’s work on refocusing in reduction semantics [13] and on use of CPS conversion and defunctionalization to convert between representations of control in interpreters [11].
A more direct approach to deriving bigstep semantics from smallstep is taken by authors of [4], where a smallstep Modular SOS specification is transformed into a prettybigstep one. This is done by introducing reflexivity and transitivity rules into a specification, along with a “refocus” rule which effectively compresses a transition sequence into a single step. The original smallstep rules are then specialized with respect to these new rules, yielding refocused rules in the style of prettybigstep semantics [6]. A related approach is by Ciobâcă [7], where bigstep rules are generated for a smallstep semantics. The bigstep rules are, again, close to a prettybigstep style.
7 Conclusion and Future Work
We have presented a stepwise functional derivation of a smallstep interpreter from a bigstep one. This derivation proceeds through a sequence of, mostly basic, transformation steps. First, the bigstep evaluation function is converted into continuationpassing style to make controlflow explicit. Then, the continuations are generalized (or lifted) to handle nonvalue inputs. The nonvalue cases correspond to congruence rules in smallstep semantics. After defunctionalization, we remove selfrecursive calls, effectively converting the recursive interpreter into a stepping function. The final major step of the transformation is to decide which continuations will have to be introduced as new auxiliary terms into the language. We have evaluated our approach on several languages covering different features. For most of these, the transformation yields smallstep semantics which are close to ones we would normally write by hand.
We see this work as an initial exploration of automatic transformations of bigstep semantics into smallstep counterparts. We identified a few areas where the current process could be significantly improved. These include applying better equational reasoning to identify terms equivalent to continuations, or transforming exceptions as state in a way that would avoid introducing many intermediate terms and would better correspond to usual signal handling in smallstep SOS. Another research avenue is to fully verify the transformations in an interactive theorem prover, with the possibility of extracting a correct transformer from the proofs.
Footnotes
 1.
The complete transformation to prettybigstep style involves these steps: 1. CPS conversion, 2. argument lifting, 3. removal of vacuous continuations, 4. defunctionalization, 5. merging of apply and eval, and 6. conversion to direct style.
Notes
Acknowledgements
We would like to thank JeanneMarie Musca, Brian LaChance and the anonymous referees for their useful comments and suggestions. This work was supported in part by DARPA award FA87501520033.
References
 1.
 2.Ager, M.S.: From natural semantics to abstract machines. In: Etalle, S. (ed.) LOPSTR 2004. LNCS, vol. 3573, pp. 245–261. Springer, Heidelberg (2005). https://doi.org/10.1007/11506676_16CrossRefGoogle Scholar
 3.Amin, N., Rompf, T.: Collapsing towers of interpreters. Proc. ACM Program. Lang. 2(POPL), 52:1–52:33 (2017). https://doi.org/10.1145/3158140CrossRefGoogle Scholar
 4.Bach Poulsen, C., Mosses, P.D.: Deriving prettybigstep semantics from smallstep semantics. In: Shao, Z. (ed.) ESOP 2014. LNCS, vol. 8410, pp. 270–289. Springer, Heidelberg (2014). https://doi.org/10.1007/9783642548338_15CrossRefGoogle Scholar
 5.Brookes, S.D., Roscoe, A.W., Walker, D.J.: An operational semantics for CSP. Technical report, Oxford University (1986)Google Scholar
 6.Charguéraud, A.: Prettybigstep semantics. In: Felleisen, M., Gardner, P. (eds.) ESOP 2013. LNCS, vol. 7792, pp. 41–60. Springer, Heidelberg (2013). https://doi.org/10.1007/9783642370366_3CrossRefGoogle Scholar
 7.Ciobâcă, Ş.: From smallstep semantics to bigstep semantics, automatically. In: Johnsen, E.B., Petre, L. (eds.) IFM 2013. LNCS, vol. 7940, pp. 347–361. Springer, Heidelberg (2013). https://doi.org/10.1007/9783642386138_24CrossRefGoogle Scholar
 8.Danvy, O., Filinski, A.: Representing control: a study of the CPS transformation. Math. Struct. Comput. Sci. 2(4), 361–391 (1992). https://doi.org/10.1017/S0960129500001535MathSciNetCrossRefzbMATHGoogle Scholar
 9.Danvy, O.: On evaluation contexts, continuations, and the rest of computation. In: Thielecke, H. (ed.) Workshop on Continuations, pp. 13–23, Technical report CSR041, Department of Computer Science, Queen Mary’s College, Venice, Italy, January 2004Google Scholar
 10.Danvy, O.: From reductionbased to reductionfree normalization. Electr. Notes Theor. Comput. Sci. 124(2), 79–100 (2005). https://doi.org/10.1016/j.entcs.2005.01.007CrossRefzbMATHGoogle Scholar
 11.Danvy, O.: Defunctionalized interpreters for programming languages. In: ICFP 2008, pp. 131–142. ACM, New York (2008). https://doi.org/10.1145/1411204.1411206
 12.Danvy, O., Johannsen, J., Zerny, I.: A walk in the semantic park. In: PEPM 2011, pp. 1–12. ACM, New York (2011). https://doi.org/10.1145/1929501.1929503
 13.Danvy, O., Nielsen, L.R.: Refocusing in reduction semantics. Technical report, BRICS RS0426, DAIMI, Department of Computer Science, University of Aarhus, November 2004Google Scholar
 14.Ellison, C., Roşu, G.: An executable formal semantics of C with applications. In: POPL 2012, pp. 533–544. ACM, New York (2012). https://doi.org/10.1145/2103656.2103719
 15.Felleisen, M., Findler, R.B., Flatt, M.: Semantics Engineering with PLT Redex, 1st edn. The MIT Press, Cambridge (2009)zbMATHGoogle Scholar
 16.Fischbach, A., Hannan, J.: Specification and correctness of lambda lifting. J. Funct. Program. 13(3), 509–543 (2003). https://doi.org/10.1017/S0956796802004604MathSciNetCrossRefzbMATHGoogle Scholar
 17.Hoare, C.A.R.: Communicating Sequential Processes. PrenticeHall Inc., Upper Saddle River (1985)zbMATHGoogle Scholar
 18.Huizing, C., Koymans, R., Kuiper, R.: A small step for mankind. In: Dams, D., Hannemann, U., Steffen, M. (eds.) Concurrency, Compositionality, and Correctness. LNCS, vol. 5930, pp. 66–73. Springer, Heidelberg (2010). https://doi.org/10.1007/9783642115127_5CrossRefGoogle Scholar
 19.Johnsson, T.: Lambda lifting: transforming programs to recursive equations. In: Jouannaud, J.P. (ed.) FPCA 1985. LNCS, vol. 201, pp. 190–203. Springer, Heidelberg (1985). https://doi.org/10.1007/3540159754_37CrossRefGoogle Scholar
 20.Klein, G., Nipkow, T.: A machinechecked model for a Javalike language, virtual machine, and compiler. ACM Trans. Program. Lang. Syst. 28(4), 619–695 (2006). https://doi.org/10.1145/1146809.1146811CrossRefGoogle Scholar
 21.Kumar, R., Myreen, M.O., Norrish, M., Owens, S.: CakeML: a verified implementation of ML. In: POPL 2014, pp. 179–191. ACM, New York (2014). https://doi.org/10.1145/2535838.2535841
 22.Leroy, X., Grall, H.: Coinductive bigstep operational semantics. Inf. Comput. 207(2), 284–304 (2009). https://doi.org/10.1016/j.ic.2007.12.004MathSciNetCrossRefzbMATHGoogle Scholar
 23.Midtgaard, J., Ramsey, N., Larsen, B.: Engineering definitional interpreters. In: PPDP 2013, pp. 121–132. ACM, New York (2013). https://doi.org/10.1145/2505879.2505894
 24.Milner, R., Tofte, M., Macqueen, D.: The Definition of Standard ML. MIT Press, Cambridge (1997)CrossRefGoogle Scholar
 25.Nielsen, L.R.: A selective CPS transformation. Electr. Notes Theor. Comput. Sci. 45, 311–331 (2001). https://doi.org/10.1016/S15710661(04)809691CrossRefzbMATHGoogle Scholar
 26.Reynolds, J.C.: Definitional interpreters for higherorder programming languages. High. Order Symbolic Comput. 11(4), 363–397 (1998). https://doi.org/10.1023/A:1010027404223CrossRefzbMATHGoogle Scholar
 27.Roşu, G., Şerbănuţă, T.F.: An overview of the K semantic framework. J. Logic Algebraic Program. 79(6), 397–434 (2010). https://doi.org/10.1016/j.jlap.2010.03.012MathSciNetCrossRefzbMATHGoogle Scholar
 28.Strachey, C., Wadsworth, C.P.: Continuations: a mathematical semantics for handling full jumps. High. Order Symbolic Comput. 13(1), 135–152 (2000). https://doi.org/10.1023/A:1010026413531CrossRefzbMATHGoogle Scholar
 29.Wright, A., Felleisen, M.: A syntactic approach to type soundness. Inf. Comput. 115(1), 38–94 (1994). https://doi.org/10.1006/inco.1994.1093MathSciNetCrossRefzbMATHGoogle Scholar
Copyright information
Open Access This chapter is licensed under the terms of the Creative Commons Attribution 4.0 International License (http://creativecommons.org/licenses/by/4.0/), which permits use, sharing, adaptation, distribution and reproduction in any medium or format, as long as you give appropriate credit to the original author(s) and the source, provide a link to the Creative Commons license and indicate if changes were made.
The images or other third party material in this chapter are included in the chapter's Creative Commons license, unless indicated otherwise in a credit line to the material. If material is not included in the chapter's Creative Commons license and your intended use is not permitted by statutory regulation or exceeds the permitted use, you will need to obtain permission directly from the copyright holder.