21.10 Introduction to Functional Programming

So far, you’ve learned structured, object-oriented and generic programming techniques. Though you often used .NET Framework classes and interfaces to perform various tasks, you typically determined what you wanted to accomplish in a task, then specified precisely how to accomplish it.

For example, let’s assume that what you’d like to accomplish is to sum the elements of an int array named values (the data source). You might use the following code:


var sum = 0;

for (var counter = 0; counter < values.Length; ++counter)
{
   sum += values[counter];
}

This loop specifies precisely how to add each array element’s value to the sum—with a for iteration statement that processes each element one at a time, adding its value to the sum. This technique is known as external iteration—because you specify how to iterate, not the library—and requires you to access the elements sequentially from beginning to end in a single thread of execution. To perform the preceding task, you also create two variables (sum and counter) that are mutated repeatedly—their values change as the iteration is performed. You performed many similar array and collection tasks, such as displaying the elements of an array, summarizing the faces of a die that was rolled 60,000,000 times, calculating the average of an array’s elements and more.

External Iteration Is Error Prone

The problem with external iteration is that even in this simple loop, there are many opportunities for error. You could, for example,

  • initialize variable sum incorrectly,

  • initialize control variable counter incorrectly,

  • use the wrong loop-continuation condition,

  • increment control variable counter incorrectly or

  • incorrectly add each value in the array to the sum.

Internal Iteration

In functional programming, you specify what you want to accomplish in a task, but not how to accomplish it. As you’ll see, to sum a numeric data source’s elements (such as those in an array or collection), you can use LINQ capabilities that allow you to say, “Here’s a data source, give me the sum of its elements.” You do not need to specify how to iterate through the elements or declare and use any mutable (that is, modifiable) variables. This is known as internal iteration, because the library code (behind the scenes) iterates through all the elements to perform the task.2

A key aspect of functional programming is immutability—not modifying the data source being processed or any other program state, such as counter-control variables in loops. By using internal iteration, you eliminate from your programs common errors that are caused by modifying data incorrectly. This makes it easier to write correct code.

Filter, Map and Reduce

Three common functional-programming operations that you’ll perform on collections of data are filter, map and reduce:

  • A filter operation results in a new collection containing only the elements that satisfy a condition. For example, you might filter a collection of ints to locate only the even integers, or you might filter a collection of Employee’s to locate people in a specific department of a large company. Filter operations do not modify the original collection.

  • A map operation results in a new collection in which each element of the original collection is mapped to a new value (possibly of a different type)—e.g., mapping numeric values to the squares of the numeric values. The new collection has the same number of elements as the collection that was mapped. Map operations do not modify the original collection.

  • A reduce operation combines the elements of a collection into a single new value typically using a lambda that specifies how to combine the elements. For example, you might reduce a collection of int grades from zero to 100 on an exam to the number of students who passed with a grade greater than or equal to 60. Reduce operations do not modify the original collection.

In the next section, we’ll demonstrate filter, map and reduce operations using class Enumerable’s LINQ to Objects extension methods Where, Select and Aggregate, respectively. The extension methods defined by class Enumerable operate on collections that implement the interface IEnumerable<T>.

C# and Functional Programming

Though C# was not originally designed as a functional-programming language, C#’s LINQ query syntax and LINQ extension methods support functional-programming techniques, such as internal iteration and immutability. In addition, C# 6’s getter-only, auto-implemented properties make it easier to define immutable types. We expect future versions of C# and most other popular programming languages to include more functional-programming capabilities that make implementing programs with a functional style more natural.

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

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