Monday, July 26, 2010

In the July 2010 presentation, for the Atlanta .Net User Group, the presenter made a comment that Lambda and closures make your code cleaner, refering to their importance in a Silverlight example and doing testing with the test framework for Silverlight. Without these language elements,the testing framework in Silverlight would either require a great deal more code and variables, or simply would not work. These language features combine to allow for small amounts of code to perform asyncrhonously. Silverlight is inherently asyncrhonous, which makes Lambda and Closures important concepts for developers to understand.

Lambda and Closures, are considered an advanced C# topic, introduced in .NET 3.0 Framework. The Lambda operator in C# is written with two characters together, an equal-sign followed by a greater-than-sign (=>). A Lambda compiles into one of two ways: the first way is it converts to a delegate instance, and the second way is it converts into a type Expression<TDelegate> - making the code inside the lambda a traversable object model - an Expression Tree - an essential element that is one of several key language pieces that LINQ is built on. The root of the lambda is a delegate, and in my discussions with other developers, some are not aware of what that is, which explains why Lambda and Closures are considered more advanced.

So to understand a Lambda, understanding what a delegate is - becomes mandatory. Delegates have been around since version .Net 1.1 of the framework, each release of the framework from 2.0 through 3.5 enhanced the basic concept of the delegate to the point that the Lambda is a superset of the delegate. Delegates are the building block of some generics -Predicate<>, Func<>, and Action<> are delegate types. Lambda builds on the foundation of delegate and generics that were introduced in earlier versions of the framework. A delegate behaves like a function pointer in C/C++, where you can assign a function to a variable(an address of a function to a variable of type pointer) allowing you to execute that function through the variable. In the case of a delegate, in .Net, you are assigning a typed method signature to a delegate variable, allowing you to execute the method from that variable,as the method signature matches the delegate signature. A signature means matching the return type, and the arguments - same argument types and number of arguments, for both method and delegate - they all have to match for the compile to work.

    class Program
    {
        //Delegate is defined with a signature(the example signature is: return an int - when passed two integers)
        delegate int GiveMeBackNewResult(int a, int b);

        static void Main(string[] args)
        {
            //Create a variable for your delegate type (which implies the same signature and return type)
            GiveMeBackNewResult varYourVariable;
            //Assign a method (of any class) to your delegate - as long as the method signature and return type matches
            varYourVariable = DiffAge;
            //Execute the method - from your variable reference to that method
            Console.WriteLine("AgeDifference:" + varYourVariable(25,43).ToString());
            //Result of "AgeDifference:18" shows in console window until you press a key.
            Console.ReadKey();
            
        }
        // Created a method that matches the delegate method signature - so we can assign to delegate
        public static int DiffAge(int firstAge, int secondAge)
        {
            //Lets just show positive numbers for an age difference.
            if (firstAge <= secondAge)
            {
                return secondAge - firstAge;
            }
            else
            {
                return firstAge - secondAge;
            }
        }
    }   
   

Delegates in this context have names, and the functions assigned to them have names. In version 2.0 of the framework, along with Generics, there was the introduction of 'anonymous methods'. Direct assignment to a delegate variable, using inline code to define a delegate,assigning the inline delegate to the delegate variable, and with no defined method name, it creates an 'anonymous method'.

   
    class Program
    {
        //Delegate is defined with a method signature(the example is return an int - when passed two integers)
        delegate int GiveMeBackNewResult(int a, int b);

        static void Main(string[] args)
        {
            //Create a variable that is an instance of your delegate
            GiveMeBackNewResult varYourVariable;
            // declaring the right side as a delegate - identifies variables first, and then uses the variables
            varYourVariable = delegate(int ageOne, int ageTwo) { if (ageOne <= ageTwo) 
							{ return ageTwo - ageOne; } 
							else 
							{ return ageOne - ageTwo; } }; 
            //Execute the method - from your variable reference to that method
            Console.WriteLine("AgeDifference:" + varYourVariable(25,43).ToString());
            //Result of "AgeDifference:18" shows in console window until you press a key.
            Console.ReadKey();
            
        }
       //NO Method defined - since we are now using an Anonymous Method assignment to the delegate variable.
    }
   

One other item to point out in the anonymous method - the return type is inferred from the delegate signature, which in this case, is an integer result. If you tried to return 'strings' - you would get a compile error for the inability to convert 'string' to 'int'. The restrictions of arguments and return types is still there, it is just composed differently in the code.

So now we have established the concept of a delegate,how delegates are the basis of the 'anonymous method', we can now move on to understand one side of the Lambda -how it compiles to a delegate - actually an 'anonymous method'. The Lambda syntax, changes one line(as determined by the semicolon) but is the exact equivalent of what we saw in the anonymous method. A Lambda has implicity typed parameters - based on the delegate.

//Replace the right side of the assignment - from delegate(var) {method} 
//-- with  a lambda expression --                         (var)=>{method}
            varYourVariable = (ageOne,ageTwo) => { if (ageOne <= ageTwo) 
							{ return ageTwo - ageOne; } 
							else
							 { return ageOne - ageTwo; } }; 

   

Closures allow variables outside the lambda expression, to be referenced within the Lambda. Closures ability to pass data through to a delegate, and then pass it on to a subsequent delegate can be a powerful concept. The presentation on Silverlight, that I started with, demonstrated how well these concepts work, you had to pass the data to a delegate due to the asyncrhonous nature of Silverlight- Asyncrhonous calls use delegates. I found Jon Skeets article, from C# in Depth, on The Beauty of Closures - the article covers the Lambda and closures and he has comparisons between Java and C# and how they approach the concepts from each language, and version of the language. I am not sure I could restate his comments on closures better - so I will direct you there. I expect that this topic will come back, in a future post, as there is a flexibility that these two features combine into, that will only become more apparent with regular use.

The idea of the Lambda goes back to Lambda calculus. The concept in computer theory goes back many years. I came across the readscheme site. connected to the programming language SCHEME (a variant of LISP). They have white papers, dating back to 1976, on Lambdas "The Original 'Lambda Papers' by Guy Steele and Gerald Sussman". It is interesting how the .Net framework is now adopting ideas that have been around for a while. The developments however are very sound and developed in a thoroughness that I must say I appreciate. It may take work to understand how to use these well, but well worth the time to learn them well.

Monday, July 26, 2010 10:30:05 PM (Eastern Standard Time, UTC-05:00)