Large to the Y combination of the novel (a)

Source: Internet
Author: User

Q: The last time the chaos of a pass, it should be the point to talk about it.

Answer: OK. Let me start by listing some of the articles I've consulted and inspired.

(1.) An article by Lao Zhao: writing recursive functions using lambda expressions

(2.) Two articles assembling the head: VS2008 Highlights: Functional programming with lambda expressions and functional programming with lambda expressions (cont.): Implementing Y-Combinations in C #

(3) The derivation process of the Y-sub (using scheme derivation), where the "derivation" is not the mathematical meaning of the derivation of the proof, but that how to guide the concept of a step-by-year, it is worth a look. It may reflect in some way how Y was invented in that year.

[There are also some articles womb can not find, which day remember to come back to fill up]

This article decided to use C # to illustrate the sample, because C # supports both normal and lambda expressions in a very good way to make comparisons easier. At the same time, it will show that other languages are different (such as js,scheme is a dynamic type language, so the implementation of Y is much simpler; F # should be the same as the Comrades brothers, there is a small difference in addition to the grammatical more indirect; C + + is a more static language, which is more difficult to implement. Requires a medium-sized technique that will be shown in later chapters).

Let's start with that old but effective example,--factorial. This is a normal recursive function:

c#int fact (int x) {return x = = 0? 1:x * Fact (x-1);}
Recursion is called the function itself in the body of the function, but the lambda expression (hereinafter referred to as Lambda) is an anonymous function, and what can be done to invoke itself? I have seen netizens have given such a ridiculous solution:
// C # func<intintnull011);

This is true for F #, which is quite similar to the previous functions in C #:

// F #  Let Rec  Fun if (x=0then1Else x * FACT (x1)

However, this does not implement the so-called anonymous recursion, because you do give yourself a name of "fact" in order to invoke itself, and it is dependent on the context. So let's define a "measure" of an anonymous recursive lambda: still taking the factorial function as an example, say I need an expression (where all the parameters are not context dependent, that is, a closure), substituting it into the following code (*), The factorial value (120) of the parameter (5) can be computed.

// C # pseudo code
int result = (*) (5);

And how do you call it without naming it for yourself? Take a look at these two lines of pseudo code, where T? represents an unknown type:

// C # pseudo code T? Fact_maker = Self = =
x = x = = 0 ? 1 : X * Self (x- 1
); int result = Fact_maker (Fact_maker) (5);

What we expect is to pass the lambda itself through the self parameter to the lambda itself (like Fact_maker (Fact_maker)) to return the red portion of the pseudo-code above (that is, the type is func<int,int> The fact function). But there is a contradiction--we want self to accept fact_maker (type Func<tself,func<int,int>> where tself represents the type of self), I also want self to play the role of fact within lambda (type func<int,int>). Therefore, this is not feasible. Since we hope that fact is the return value of self, try this:

funct<tself,func< int ,int01  
Self (self)
1);

To analyze this, the type of self should be the return type of func<tself,func<int,int>>,self (self), which is exactly func<int,int> fact_ Maker is also this type, can be smoothly passed by self, everything is very harmonious. So what's the tself to say? It accepts itself, and returns FUNC<INT,INT> So I define such a delegate (Ouroboros means a snake that bites its tail to form a ring):

// C # Delegate T ouroborosfunc<t> (oroborosfunc<t> self);

This ouroborosfunc<func<int,int>> is exactly the self type we need. Here, you can test the above ideas to see if you can work well.

// C # ouroborosfunc<func<intint011); int result = Fact_maker (Fact_maker) (5); Console.WriteLine (result);   //  -

Very good, the output of the correct results. If you want to, you can apply this lambda to the same lambda without needing this fact_maker, but pay attention to explicitly declaring the type, because C # does not allow lambda automatic type inference, like this:

//C # intresult = ((ouroborosfunc<func<int,int>>) ( self= = X = = = =0?1: X * Self (self) (X-1)) ) ((Ouroborosfunc<Func<int,int>>) ( self= = X = = = =0?1: X * Self (self) (X-1)))(5);  Console.WriteLine (result); // -

Well, it's not bad, although it's a little ugly, but it still satisfies the previous definition of anonymous recursion.

Q: But ... I still haven't talked about Y-combos ...

A: Anonymous recursion is done in the first place, but it has no reusability and is immortal. There are still a lot of ways to go, please be patient.

Large to the Y combination of the novel (a)

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.