locked
Lambda expression confusion RRS feed

  • Question

  • Func<int, int> fib = null;
    fib = (x) => x > 1 ? fib(x-1) + fib(x-2) : x;
    Console.WriteLine(fib(4));

    Would you please explain line 2 of above code. I donot know how this works?
    It prints 3 on conslole but I'm trying to diguest/absorb line 2.
    I know, in code below, if 3 is greater than 4, b is assigned literal Yes otherwise it gets assigned No.
    But i cannot apply the same pattern on line 2 of the code above. Thanks much.

    string b = 3 > 4 ? "Yes" : "No";
    Console.WriteLine(b);

     

    Thursday, December 10, 2009 9:57 PM

Answers


  • Maybe it would help to look at the code written without a lambda:

    using System;
    
    namespace ConsoleApplication56
    {
        class Program
        {
            static void Main ( string[] args )
            {
                Console.WriteLine ( fib ( 4 ) );
            }
    
            private static int fib ( int x )
            {
                return ( x > 1 ) ? fib ( x - 1 ) + fib ( x - 2 ) : x;
            }
        }
    }
    As you can see, this will print 3 just as the original code.  fib is a recursive implementation of the fibonacci sequence...

    Now, to understand your line of code:

    using System;
    
    namespace ConsoleApplication56
    {
        class Program
        {
            static void Main ( string[] args )
            {
                Func<int, int> fib = null;
                fib = ( x ) => x > 1 ? fib ( x - 1 ) + fib ( x - 2 ) : x;
                Console.WriteLine ( fib ( 4 ) );
                
            }
        }
    }
    
    In this case, we are pretty much doing the same thing.  We are defining the variable fib as a delegate of type Func<int, int> - or basically, that it is a function that takes an int and returns an int.  Then, in the line in question, we are defining the actual function that is assigned to the variable fib - this is a short cut syntax really of anonymous delegates in C#2.0, though lambda's are a bit more flexible.   The ( x ) part is defining the argument - you don't have to specifiy the type here because the compiler is able to infer the type from the declaration of the fib variable - it knows it's an int.  The next part is the lambda operator =>  it is read as "goes to".  So, so far we have said something along the lines of "fib equals, x goes to". 

    Everything after the lambda operator (=>) is the body of the function - the recursive definition of the fibonacci sequence.  Basically, if x is greater then 1, return fib(x-1) + fib(x-2) else return x.

    HTH
    Tom Shelton
    • Proposed as answer by Danijel MalikMVP Saturday, December 12, 2009 2:06 AM
    • Marked as answer by Bin-ze Zhao Wednesday, December 16, 2009 8:15 AM
    Thursday, December 10, 2009 10:26 PM
  • Hi,

    It's a recursion...and can be translated into this:

    Func<int, int> fib = null;
    fib = delegate(int x)
    {
        if (x > 1)
        {
            return fib(x - 1) + fib(x - 2);
        }
        else
        {
            return x;
        }
    };
    Console.WriteLine(fib(4));

    Now let's analyse your code. I will explain you each part of the statement itself.
    fib = (x) => x > 1 ? fib(x - 1) + fib(x - 2) : x; // this could be translated like foreach x in a set
    fib = (x) => x > 1 ? fib(x - 1) + fib(x - 2) : x; // that's a condition...look at the code above..this equals to if (x > 1)
    fib = (x) => x > 1 ? fib(x - 1) + fib(x - 2) : x; // this is a recursion part...i predict that you know how to calculate fibonacci
    fib = (x) => x > 1 ? fib(x - 1) + fib(x - 2) : x; // and that's else statement

    Is everything clear now?
    Regards, Danijel http://arkcore.wordpress.com
    • Proposed as answer by Danijel MalikMVP Saturday, December 12, 2009 2:06 AM
    • Marked as answer by Bin-ze Zhao Wednesday, December 16, 2009 8:15 AM
    Thursday, December 10, 2009 11:23 PM

All replies


  • Maybe it would help to look at the code written without a lambda:

    using System;
    
    namespace ConsoleApplication56
    {
        class Program
        {
            static void Main ( string[] args )
            {
                Console.WriteLine ( fib ( 4 ) );
            }
    
            private static int fib ( int x )
            {
                return ( x > 1 ) ? fib ( x - 1 ) + fib ( x - 2 ) : x;
            }
        }
    }
    As you can see, this will print 3 just as the original code.  fib is a recursive implementation of the fibonacci sequence...

    Now, to understand your line of code:

    using System;
    
    namespace ConsoleApplication56
    {
        class Program
        {
            static void Main ( string[] args )
            {
                Func<int, int> fib = null;
                fib = ( x ) => x > 1 ? fib ( x - 1 ) + fib ( x - 2 ) : x;
                Console.WriteLine ( fib ( 4 ) );
                
            }
        }
    }
    
    In this case, we are pretty much doing the same thing.  We are defining the variable fib as a delegate of type Func<int, int> - or basically, that it is a function that takes an int and returns an int.  Then, in the line in question, we are defining the actual function that is assigned to the variable fib - this is a short cut syntax really of anonymous delegates in C#2.0, though lambda's are a bit more flexible.   The ( x ) part is defining the argument - you don't have to specifiy the type here because the compiler is able to infer the type from the declaration of the fib variable - it knows it's an int.  The next part is the lambda operator =>  it is read as "goes to".  So, so far we have said something along the lines of "fib equals, x goes to". 

    Everything after the lambda operator (=>) is the body of the function - the recursive definition of the fibonacci sequence.  Basically, if x is greater then 1, return fib(x-1) + fib(x-2) else return x.

    HTH
    Tom Shelton
    • Proposed as answer by Danijel MalikMVP Saturday, December 12, 2009 2:06 AM
    • Marked as answer by Bin-ze Zhao Wednesday, December 16, 2009 8:15 AM
    Thursday, December 10, 2009 10:26 PM
  • Hi,

    It's a recursion...and can be translated into this:

    Func<int, int> fib = null;
    fib = delegate(int x)
    {
        if (x > 1)
        {
            return fib(x - 1) + fib(x - 2);
        }
        else
        {
            return x;
        }
    };
    Console.WriteLine(fib(4));

    Now let's analyse your code. I will explain you each part of the statement itself.
    fib = (x) => x > 1 ? fib(x - 1) + fib(x - 2) : x; // this could be translated like foreach x in a set
    fib = (x) => x > 1 ? fib(x - 1) + fib(x - 2) : x; // that's a condition...look at the code above..this equals to if (x > 1)
    fib = (x) => x > 1 ? fib(x - 1) + fib(x - 2) : x; // this is a recursion part...i predict that you know how to calculate fibonacci
    fib = (x) => x > 1 ? fib(x - 1) + fib(x - 2) : x; // and that's else statement

    Is everything clear now?
    Regards, Danijel http://arkcore.wordpress.com
    • Proposed as answer by Danijel MalikMVP Saturday, December 12, 2009 2:06 AM
    • Marked as answer by Bin-ze Zhao Wednesday, December 16, 2009 8:15 AM
    Thursday, December 10, 2009 11:23 PM
  • I didn't even see Tom's answer.


    Regards, Danijel http://arkcore.wordpress.com
    Thursday, December 10, 2009 11:42 PM
  • Tom, Thanks so much. You were a great help.
    Friday, December 11, 2009 6:22 PM
  • Thanks Danijel your help, I understand the code now.
    Friday, December 11, 2009 6:23 PM