"Continuation-passing style is a notation
notation that makes explicit every aspect of the control and data
control and data flow" (Andrew W. Appel).
The CPS Technique
Definición
CPS is a functional programming technique consisting of the following:
In a function f(x), of parameter(s) x, an extra parameter < i>c, which represents a more general function, i.e., f(x, c).
The new function, with arguments a and c, does not return the result r = f(a ), but the result of applying the function c to r, i.e., c(r) = c(f(a)). In general, f(x, c) = c(f(x)).
The function c with argument r represents what "remains to be done" (after obtaining the first result r) to complete the final result of the function f. That is why c is called "continuation function" or, simply, "continuation". And the function that includes as parameter a continuation function is called "function with continuation" or "CPS function".
Difference between the functions f(a, c) and c(f(a))
In both cases the result is the same, but there are important differences:
In the first function, c is a parameter and in the second one it is not.
In the first function, after executing and obtaining the result r, c (with argument r) is called. Subsequently, the control is returned. In the second function, after obtaining r, there is return (of the result and of the control) to the function c.
In the first case, there may be higher-order continuations, i.e., the continuation could in turn invoke another function with continuation, which in turn could call another function with continuation, etc., so the function is functionally open. In the second case, the function is functionally closed.
Implementation in MENTAL
Specification
The CPS function in MENTAL can be represented in the classical form (with parameters in parentheses) f(x c) being:
x: parameter(s) of the function f.
c: function continuation.
Definition:
〈( f(x c) = c(f(x)) )〉
Example
Normal style.
Function definition:
〈( square(x) = x*x )〉
Function usage:
square(4) // ev. 4*4 ev. 16
CPS.
Function definition (an additional parameter is added):
〈( square(x c) = c(x*x) )〉
Definition of a function continued:
〈( sum5(x) = x+5 )〉
The higher-order continuation functions could, in turn, have parameters.
Beyond CPS. The parameterization of expressions
The CPS technique is the functional parameterization of functions, but it is a particular case of the general case of adding parameters to expressions, which can be done in MENTAL.
All kinds of expressions (functions, rules, objects, data, etc.) can be parameterized.
Parameters can be inserted at strategic points to facilitate their later use in a more generic way.
The same parameter can be instantiated as a function or as data.
You can add as many parameters as you want to the expressions.
Examples of function on intermediate results (not on the final result):
In traditional programming languages, f is fixed (it cannot be variable). In MENTAL, it can be variable, so the concept of continuation is irrelevant, since it makes no difference whether the continuation is included as a parameter or as a function. For example,
The CPS technique can be considered as a high-level parameterized branching (goto), since a call to a continuation function is actually a jump to another part of the program.
By introducing an additional parameter in the function definition, functions are generalized. Another way of looking at it is to say that the original language is extended and made more flexible.
Paradoxically, at the same time, we can find ourselves with an environment of a lower level of abstraction, of greater detail, because the computational sequences are made explicit. This is why this technique is used internally in compilers and interpreters of programming languages, especially functional ones, to successively approximate a high-level language to another low-level language (such as machine code) by means of sequences of expressions.
In fact, a certain analogy can be established between a program made with continuations and a von Neumann-type machine, where the CPS execution sequences would correspond to the instructions and the variables to the registers of the machine.
If a program is performed entirely with continuations, then returns (control and value returns) are completely eliminated. Consequently, there is no need to internally use a stack for storing these values, making such an implementation simpler.
The execution would consist of a sequence of the form.
(f1(a1 c1) f2(a2 c2) f3(a3 c3) ...)
being:
fi: function with continuation
ai: argument(s)
ci: continuation
The environment is dragged from one element to the next and calls and data are made explicit.
CPS has the effect of linearizing the execution of a program, as opposed to the classical programming system, which we can qualify as "reactive", since each call corresponds to a return with a response.
Any traditional function can be rewritten in CPS, so it is possible to discard the stack completely and use only continuations.
The CPS technique has an advantage over normal functions when the result of the function involves a large amount of data, since there is no need to group them together to return as a result, nor is there a need to collect them in the calling function.
What is obtained with the CPS technique is not a higher order function (function of function), since this concept corresponds to that of a function in which the parameters are functions and the result is another function.
Applications of the CPS technique
The CPS technique was born in the late 1960s. Since then, in addition to its aforementioned application in the development of compilers and interpreters, it has also been applied in a variety of areas:
Program transformation.
Generators.
Exceptions.
Remote procedure calls.
Persistent computing.
Concurrent programming.
Event-driven programming.
Etc.
Bibliography
Applel, Andrew W. Compiling with Continuations. Cambridge University Press, 1992.
Friedman, D.P.; Wand, M.; Heynes, C.T. Essentials of Programming Languages. The MIT Press, 1992. [Cubre el tema CPS en profundidad con el lenguaje functional Scheme.]
Jones, Neil. D.; Gomard, Carsten K.; Sestoff, Meter. Partial Evaluation and Automatic Program Generation. Prentice Hall International Series in Computer Science, 1993. [Se estudia CPS como técnica en la generación de programas.]
Kalsey, Richard A. A correspondence between continuation passing style and static single assignement form. ACM SIGPLAN Notices, 30(3): 13-22, March 1995.
Sabry, Amr; Felleisen, Mathias. Reasoning about programs in continuation-passing style. Lisp and Symbolic Computation, 6(3-4):289-360, 1993.
Stansifer, Ryan. The Study of Programming Languages. Prentice-Hall, New Jersey, 1995. [Trata el tema CPS en el contexto del cálculo lambda.]