When and how to use continuation passing style

后端 未结 3 1379
执笔经年
执笔经年 2021-02-07 12:51

I have been reading about the continuation passing style programming technique (C# 3.0 implementation).

Why/when it would be useful to use this technique?

How ca

3条回答
  •  既然无缘
    2021-02-07 13:53

    I have found a short and good explanation for CPS in the book “Concurrency in .NET, Modern patterns of concurrent and parallel programming” by Riccardo Terrell (the code is in C#):

    Sometimes, optimized tail-call recursive functions aren’t the right solution or can be difficult to implement. In this case, one possible alternative approach is CPS, a technique to pass the result of a function into a continuation. CPS is used to optimize recursive functions because it avoids stack allocation. Moreover, CPS is used in the Microsoft TPL, in async/await in C#, and in async-workflow in F#. CPS plays an important role in concurrent programming. This following code example shows how the CPS pattern is used in a function GetMaxCPS:

    static void GetMaxCPS(int x, int y, Action action) => action(x > y ? x : y);
    
    GetMaxCPS (5, 7, n => Console.WriteLine(n));
    

    The argument for the continuation passing is defined as a delegate Action, which can be used conveniently to pass a lambda expression. The interesting part is that the function with this design never returns a result directly; instead, it supplies the result to the continuation procedure. CPS can also be used to implement recursive functions using tail calls.

    Here is also a simple and short explanation from Wikipedia. The explanation also mentions the benefits of CPS:

    https://en.wikipedia.org/wiki/Continuation-passing_style

    A function written in continuation-passing style takes an extra argument: an explicit "continuation", i.e. a function of one argument. When the CPS function has computed its result value, it "returns" it by calling the continuation function with this value as the argument. That means that when invoking a CPS function, the calling function is required to supply a procedure to be invoked with the subroutine's "return" value. Expressing code in this form makes a number of things explicit which are implicit in direct style. These include: procedure returns, which become apparent as calls to a continuation; intermediate values, which are all given names; order of argument evaluation, which is made explicit; and tail calls, which simply call a procedure with the same continuation, unmodified, that was passed to the caller.

    Programming with continuations can also be useful when a caller does not want to wait until the callee completes. For example, in user-interface (UI) programming, a routine can set up dialog box fields and pass these, along with a continuation function, to the UI framework. This call returns right away, allowing the application code to continue while the user interacts with the dialog box. Once the user presses the "OK" button, the framework calls the continuation function with the updated fields.

提交回复
热议问题