The advantages of using lambda expression in functional programming

Lambda expressions are not only a powerful way to provide a shorthand notation for anonymous methods, but they are also used in functional programming. In this section, we will go through the advantages of using the lambda expression in the context of functional programming.

First-class functions

In Chapter 1, Tasting Functional Style in C#, we discussed the idea of first-class functions when we were discussing functional programming. If functions are fire class Functions, functions obey value semantics. They can be passed as a parameter, returned from a function, and so on. If we go back to the earlier topic about lambda expressions, we have a project named SimpleLambdaExpression.csproj, which has the following simple lambda expression:

public partial class Program 
{ 
  static Func<string, string> displayMessageDelegate = 
    str => String.Format(Message: {0}", str); 
} 

Then, we can add the following firstClassConcept() method to the project in order to demonstrate the first-class function using a lambda expression:

public partial class Program 
{ 
  static private void firstClassConcept() 
  { 
    string str = displayMessageDelegate( 
      "Assign displayMessageDelegate() to variable"); 
      Console.WriteLine(str); 
  } 
} 

As we can see, we have successfully assigned the displayMessageDelegate() method to the variable named str, as follows:

string str = displayMessageDelegate( 
  "Assign displayMessageDelegate() to variable"); 

If we run the code, we will get the following output on the console:

First-class functions

We can also pass the lambda expression as the argument of the other function. Using displayMessageDelegate, let's take a look at the following code:

public partial class Program 
{ 
  static private void firstClassConcept2( 
    Func<string, string> funct, 
    string message) 
  { 
    Console.WriteLine(funct(message)); 
  } 
} 

We have a method named firstClassConcept2, which takes Func and string parameters. We can run the method as follows:

public partial class Program 
{ 
  static void Main(string[] args) 
  { 
    firstClassConcept2( 
      displayMessageDelegate, 
      "Pass lambda expression to argument"); 
  } 
} 

As we can see, we pass displayMessageDelegate, which is a lambda expression, to the firstClassConcept2() method. If we run the project, we will have the following output on the console window:

First-class functions

Since we have successfully assigned a function to a variable and passed a function to another function parameter, we can say that the lambda expression is a power tool to create first-class functions in functional programming.

Closure

Closure is a function that is able to be assigned to a variable (a first-class function) with free variables, which are bound in the lexical environment. A free variable is a variable that is not a parameter; or it is a local variable. In a closure, any variable that is not bound will be captured from the lexical environment where the closure is defined. To avoid getting confused about this term, let's take a look at the following code, which we can find in the Closure.csproj project:

public partial class Program 
{ 
  private static Func<int, int> GetFunction() 
  { 
    int localVar = 1; 
    Func<int, int> returnFunc = scopeVar => 
    { 
      localVar *= 2; 
      return scopeVar + localVar; 
    }; 
  return returnFunc; 
  } 
} 

From the preceding code, we can see that we've got a local variable named localVar, and it will be multiplied by 2 when the GetFunction() method is invoked. The localVar variable is bound inside the lambda expression when returnValue is returned. By analyzing the preceding code without running it, we might guess that GetFunction() will return returnFunc, which will always return the same value every time it's passed to the same argument. This is because localVar will always be 1 every time GetFunction() is invoked, since it's a local variable. As we learned in programming, the local variables are created on the stack and they will go away when the method has finished execution. Now, let's invoke the GetFunction() method to prove our guess using the following code:

public partial class Program 
{ 
  static void Main(string[] args) 
  { 
    Func<int, int> incrementFunc = GetFunction(); 
    for (int i = 0; i < 10; i++) 
    { 
      Console.WriteLine( 
        "Invoking {0}: incrementFunc(1) = {1}", 
        i, 
        incrementFunc(1)); 
    } 
  } 
} 

We are going to invoke the incrementFunc() method, which is the return value of the GetFunction() method ten times, but we always pass 1 as the argument. From our previous guessing, we can say that the incrementFunc(1) method will always return 3 for all ten invocations. Now, let's run the project, and we will see the following output on the console:

Closure

According to the preceding output, we made a wrong guess. The localVar variable lives along with the GetFunction() method. It stores its value after being multiplied by 2 each time the method is called. We have successfully bound a free variable in the lexical environment and this is what we call closure.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset