Exploring recursive APS and CPS in c #

Source: Internet
Author: User

Exploring recursive APS and CPS in c #

Accumulator passing style)

Tail recursion is optimized so that the stack does not need to save the last returned address/status value, so that the recursive function is treated as a common function call.

Recursion is actually dependent on the previous value to calculate the next value. If we can save the last value and pass it in the next call without directly referencing the value returned by the function. So that the stack is released, and tail recursion optimization is achieved.

Next, we add the acc parameter, which stores the last value and is passed in during the next call.

Static int Accumulate (int acc, int n)

{

If (n = 0)

Return acc;

Return accumulate (acc * n, n-1 );

}

When using Accumulate recursion, we only need to use the last return value. The call is as follows:

Var ac = Accumulate (1, 20 );

Use Lambda expressions to implement tail recursion factorial:

Static int AccumulateByLambda (int x)

{

Func accumulate = null;

Accumulate = (acc, n) => n = 0? Acc: Accumulate (acc * n, n-1 );

Return accumulate (1, x );

}

CPS Functions

CPS stands for the Continuation passing style.

Static int Times3 (int x)

{

Return x * 3;

}

Console. WriteLine (Times3 (5 ));

The above function times the input value by 3, which is usually written in this way. In fact, we can also use the C # syntax of the returned function to construct the nested method and change the function call to the call chain times3 (3) (5 ).

This method is intuitive and normal in mathematics or functional programming, but it is not so intuitive in the script language c.

The Continuation term in CPS refers to the remainder of the computation, similar to the times3 (3) (5) red part.

For example, the expression a * (B + c) has multiple calculation steps. C # can be written as the following function:

Console. WriteLine (Mult (a, Add (B, c )))

The procedure is as follows:

B and c are added.

Multiply the result by.

Output result.

When one step is performed, the subsequent operations are 2 or 3. When two steps are performed, the subsequent operation is 3. Use the CPS mode to transform the times3 function:

Static void Times3CPS (int x, Action continuation)

{

Continuation (x * 3 );

}

Times3CPS (5, (reslut) => Console. WriteLine (result ));

We added a function parameter indicating the next operation 3, and passed the subsequent operation during the call. This is the CPS function.

CPS Transformation

After learning about the CPS function, let's take a closer look at the CPS transformation.

Console. WriteLine (Times3 (5 ));

// CPS Transformation

Times3CPS (5, (reslut) => Console. WriteLine (result ));

The above times3 function is called CPS conversion from direct calls to the use of "subsequent transfer operations.

Example 1: MAX Function Conversion

Static int Max (int n, int m)

{

If (n> m)

Return n;

Else

Return m;

}

Console. WriteLine (Max (3, 4 ));

To convert the max function to the CPS mode, perform the following steps:

1: Change the return value to void.

2: add an additional type parameter Action. T is the original return type.

3: replace all original return declarations with the parameters of subsequent operation expressions.

Static void Max (int n, int m, Action k)

{

If (n> m)

K (n );

Else

K (m );

}

Max (3, 4, x => Console. WriteLine (x ));

Example 2: if there are three functions Main, F, and G, Main calls F and F call G.

Console. WriteLine (F (1) + 1 );

Static int F (int n)

{

Return G (n + 1) + 1;

}

Static int G (int n)

{

Return n + 1;

}

We Convert F and G to the CPS style. The conversion steps are the same as those of Max functions:

F (1, x => Console. WriteLine (x + 1 ));

Static void F (int n, Action k)

{

G (n + 1, x => k (x + 1 ));

}

Static void G (int n, Action k)

{

K (n + 1 );

}

CPS tail recursion

This is a traditional recursive factorial:

Static int Factorial (int n)

{

If (n = 0)

Return 1;

Else

Return n * Factorial (n-1 );

}

Use the same procedure to convert recursion to CPS tail recursion:

Factorial (5, x => Console. WriteLine (x ));

Static void Factorial (int n, Action continuation)

{

If (n = 0)

Continuation (1 );

Else

Factorial (n-1, x => continuation (n * x ));

}

Lazhao-tail recursion and Continuation

"Calculate the factorial of n, pass the result into the continuation method, and return", that is, "Calculate the factorial of n-1, multiply the result with n, and then call the continuation method ". To implement the logic of "multiply the result with n and then call the continuation method", the Code constructs an anonymous method and passes in the Factorial method again.

Summary

The CPS mode is very powerful and can be used in many aspects. For example, in the implementation of the compiler, the CPS-style parser combination sub-, and callback after the function is completed. It can also be said that the original internal control operations of the program are extracted by using the CPS method and exposed to the programmer, for example, the example in this article.

Note: For more exciting tutorials, please follow the help houseWebpage Design tutorialTopic,

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.