Concurrency Semantics in Continuation-Passing Style — The
Total Page:16
File Type:pdf, Size:1020Kb
Concurrency Semantics in Continuation-Passing Style∗ — The Companion Technical Report — Eneia Nicolae Todoran Technical University of Cluj-Napoca Department of Computer Science Baritiu Str. 28, 400027, Cluj-Napoca, Romania. [email protected] Nikolaos S. Papaspyrou National Technical University of Athens School of Electrical and Computer Engineering Software Engineering Laboratory Polytechnioupoli, 15780 Zografou, Greece. [email protected] Abstract By using the mathematical framework of metric semantics we develop a denotational semantics designed in continuation-passing style for an abstract concurrent language providing a general mech- anism of interaction between multisets of distributed actions. The basic laws of concurrent systems are satisfied in this semantics. Next, by customizing the behavior of continuations we obtain denota- tional semantics for a couple of concurrent languages incorporating mechanisms for multiparty and binary interactions. We offer denotational semantics for two imperative concurrent languages based on Hoare’s CSP and a process algebra for DNA computing introduced by Cardelli. Keywords: continuation-passing style, denotational semantics, metric spaces, concurrency semantics 1 Introduction Continuations are a very powerful control-flow mechanism. As abstract representations of control flow, they were introduced in the 1960s and soon came into prominence in the field of denotational semantics for modelling the semantics of programming languages [23, 38, 34]. In a few words, a continuation represents control flow by capturing the notion of “the rest of the program”, after the current point during the program’s execution. Some functional languages, such as Scheme [22] and SML/NJ [37], provide direct support for capturing and invoking continuations, which are treated as first-class values. In such languages, continuations can be used to implement a variety of advanced control flow constructs. They roughly correspond to “jumps” to different places; programmers can use them as a low-level mechanism to implement disciplined (or undisciplined) “goto”, resumable exceptions, or even coroutines. Continuation-passing style (CPS) is the style of programming in which control is passed explicitly in the form of continuations, in contrast to direct style, which is the usual style of programming. In direct style, a function is called with a number of arguments, it evaluates its result, and returns it to the caller. In CPS, on the other hand, functions never return to the caller. They receive as an additional argument a continuation (or more than one, if necessary), which they invoke with the value of their result, as soon as that is computed. Programs in direct style can be automatically translated to CPS [13]. Indeed CPS ∗Printed: August 2016, Revised April 2017 1 is commonly employed in the development of optimizing compilers for languages with higher-order functions [3]. In recent years, CPS has found a significant practical use for synchronous or asynchronous web programming [31, 32, 12, 21]. Continuations do not only generalize the notion of a “callback” function that is standard in web programming. They can be used to circumvent the statelessness of the HTTP protocol which, in the traditional model of web programming, typically leads to poorly structured code. Several continuation-aware web servers and web frameworks have been developed [47, 44, 48, 35] and have known varying degrees of popularity. In the semantics of programming languages, continuations can be used to model a variety of advanced control concepts, including nonlocal exits, exceptions, coroutines [18] and even multitasking [46, 14]. Various forms of delimited continuations [15, 16, 36, 33, 13, 19, 25] provide even finer control than traditional continuations; they represent a part of the rest of what remains to be computed and they allow (or impose) a more structured way to the use of continuations. However, it is generally believed that traditional continuations do not work well in the presence of concurrency [19]. In the words of Mosses, from his more recent survey of programming language description languages [27]: “Although continuation-passing style is sometimes regarded as a standard style to use for de- notational semantics, it is inadequate for describing languages that involve non-determinism or concurrent processes.” We argue that the fault lies not with the use of CPS, either as a programming style or as a tool for modeling denotational semantics, but with the standard, traditional notion of continuation, which is inadequate to describe certain aspects of concurrency. To alleviate this problem, in our previous publications we have introduced the continuation semantics for concurrency (CSC) technique and we have used it for defining the semantics of several concurrent languages [40, 9]. CSC provides a general tool for modelling control in concurrent systems and it can be used to design both operational and denotational semantic models. When used for the latter, the dis- tinctive characteristic of the CSC technique is that continuations are modelled as appropriate structures of computations (denotations). The structure of continuations is representative of the control flow con- cepts of the languages under study. Computations are also called processes in [40]. Intuitively, CSC is a semantic formalization of a process scheduler. Processes are grouped in what is called a continuation, and the term process denotes the (partially evaluated) meaning of a statement. The concurrency control concepts themselves are modelled as operations manipulating continuations. The domain of CSC can be defined based on a set Id of (process) identifiers. The set of identifiers Id is endowed with a partial order, which induces the structure of continuations specific of the language under investigation. For ex- ample, in [42, 41] continuations are multisets of computations that are executed in parallel. In [40, 9, 10] continuations are trees of computations with active computations at the leaves. In this paper, we propose a different solution by focusing on a much simpler structure for contin- uations, more reminiscent of traditional continuations. We investigate the denotational semantics of concurrent systems in classic continuation-passing style (CPS) based on the interplay between compu- tations (denotations), interaction multisets, synchronous and asynchronous continuations. Our notion of a synchronous continuation roughly coincides with the traditional one: a function that awaits a value and represents the “rest of the program” by yielding its final result. However, the awaited value encom- passes an asynchronous continuation, which may contain a suspended computation, in a way similar to that used by resumption-based approaches to concurrency [11]. We argue that this enhanced notion of continuation provides the necessary structure that is missing from the traditional approach. When a computation is evaluated with respect to a synchronous continuation, the computation is decomposed into an interaction multiset and an asynchronous continuation, which are transmitted as parameters to the synchronous continuation. We offer denotational semantics designed in CPS for various binary and multiparty interaction mechanisms. We hope to collect sufficient evidence that CPS can be used as a general tool for designing denotational semantics for concurrent languages. 2 Note that CSC (continuation semantics for concurrency [40, 9]) and CPS (continuation-passing style) are different techniques, relying on different (classes of) domains and different evaluation strategies for continuations. CSC captures the flow of control by explicit manipulations of process identifiers and requires silent steps to handle synchronous interactions [40, 42, 10], that are not needed in the CPS- based approach that we introduce in this paper. Also, using classic CPS, in this work we establish laws of synchronous interactions that have not been investigated for CSC. Unlike other semantic models of concurrency [30, 5], in the CPS approach that we introduce in this paper the final yield of the semantic functions is a simple collection of observations assembled in a linear time domain. No branching structure is needed. All communication and concurrency control concepts are modelled as operations manipulating continuations. The terms linear time and branching time are often used in temporal logic and semantics [5]. Intuitively, an element of a linear time domain is a collection of (execution) traces. An element of a branching time domain is a tree like structure. Following de Bakker and de Vink [5] in this paper we use the mathematical methodology of metric semantics. The main mathematical tool in this approach to semantics is Banach’s theorem which states that contracting functions on complete metric spaces have unique fixed points. The metric domains that we use to express computation are complete metric spaces. We use the general method for solving reflexive domain equations (in a category of complete metric spaces) developed by America and Rutten [2] as our domain of computations is defined as the solution of an equation where the domain variable occurs in the left hand side of a function space construction. The rest of this paper is organized as follows. In sections 3 and 4 we introduce an abstract con- current language L providing a general mechanism of of interaction between multisets of distributed actions. In section 4 we define a denotational semantics for L. The denotational semantics