Function programming in C #: Preface (1 ),

Source: Internet
Author: User

Function programming in C #: Preface (1 ),

I have been studying functional programming languages for so long and have always wanted to write some related articles. After a period of consideration, I decided to open this trap.

As for why C # is selected, in my opinion, there are three types of programming languages: one is a language that is difficult to implement functional programming, including Java 6 and C. This type of language does not support anonymous functions and other features, making functional programming more difficult. One is a language that claims to be a "functional programming language, includes Scala, Clojure, F #, Haskell, etc. This type of language attaches great importance to functional programming. Its teaching materials usually contain functional programming knowledge. Therefore, most users of these languages have mastered functional programming skills; there is another type of programming language, which is not called a functional programming language, but can be used for functional programming. There are fewer users who know functional programming in these languages, and fewer learning materials refer to functional programming. These languages include Java8, C ++ 11, C #, Rust, Kotlin, TypeScript, Python, and Ruby.

Since my article is about functional programming, first of all, I certainly cannot select the first type and they cannot be used. Users of the second type of programming language have mastered the functional programming skills. Considering the audience, my selection is within the third language. Finally, I selected C # through a random number. If I had the energy, I would try other languages.

So much, then what is functional programming? According to Martin Odersky, the father of Scala, functional programming has narrow and broad meanings: narrow functional programming refers to programming without side effects of expressions, the programming languages that meet this need include Pure Lisp and Haskell subsets that do not contain IO Monad and Unsafe operations. In a broad sense, function programming refers to the language in which functions are the first citizens, this range is much larger. The second and third types of languages mentioned above belong to generalized functional programming.

The core of functional programming is related to these two definitions: no side effects, and functions are the first citizens.

Let's look at the side effects first. I remember when I used to study C language, some people liked to use x ++ x as an example to write an notorious C language book. This expression is actually an undefined action. However, if we replace it with (x + 1) + (x + 2), this statement is unambiguous. The problem is that x ++ and ++ x have side effects.If an expression has no side effects, we can use the value of this expression.Replace itBut the behavior of the program will not change.We call this Property Reference transparent (Referential Transparency). In the preceding example, if the value of x is 3, we can replace x + 1 with its value 4 for (x + 1) + (x + 2, then, the expression is rewritten to 4 + (x + 2), or x + 2 is replaced with 5 and then changed to (x + 1) + 5. This rewrite will not change the value of the expression. However, x ++ is not allowed. If we replace x ++ with 3, the value of the expression will change. Therefore, x ++ and ++ x are not transparent references.

One of the major features of referencing transparency is that we can change the execution sequence of referencing transparent expressions without worrying about changes in program behavior. The reason why x ++ x is undefined is that x ++ and ++ x are not reference transparent, as a result, the order in which x ++ and ++ x are executed will affect the value of the entire expression. The order of x + 1 and x + 2 does not affect the value of the expression. This feature will be used later.

The following is another example. Consider the C # code section.

 1 class Program 2 { 3     static void Main() 4     { 5         for (int i = 0; i < 10; ++i) 6         { 7             System.Threading.Tasks.Task.Factory.StartNew(() => 8             { 9                 System.Threading.Thread.Sleep(100);10                 System.Console.WriteLine(i);11             });12         }13         System.Console.ReadLine();14     }15 }

What will this code output?

You may think it will output numbers 0 to 9 in some order, but the actual output is 10 digits 10.

To allow the program to output numbers 0 to 9, we need to modify the program as follows:

 1 class Program 2 { 3     static void Main() 4     { 5         for (int i = 0; i < 10; ++i) 6         { 7             int _i = i; 8             System.Threading.Tasks.Task.Factory.StartNew(() => 9             {10                 System.Threading.Thread.Sleep(100);11                 System.Console.WriteLine(_i);12             });13         }14         System.Console.ReadLine();15     }16 }

If you are a JavaScript programmer, you may be familiar with this strategy. This is a common pitfall when you create a closure in a loop (that is, an anonymous function that uses external variables. For the previous program, because the I of the cyclic variable changes, I does not meet the reference transparency. We cannot replace I with the I value when creating the closure, due to the existence of the Sleep statement, the value of I in the final output is 10. The second program outputs not I, but _ I, _ I satisfiesNo value is assigned again after initialization., Which is an important feature of variable transparency. In this case, we can replace _ I with the value of _ I, so that the program can output numbers 0 ~ 9.

As shown in the preceding example, side effects may produce inadvertent bugs. Therefore, in functional programming, we will try to minimize side effects. For example, the above Code, the most perfect solution is to use the tail recursion we will mention later.

Another feature of functional programming is that the function is the first citizen. In many traditional programming languages, functions have many restrictions. For example, we cannot define functions within a function, and we cannot create a variable of the function type (note: the function pointer in C language is strictly not counted. Because the function pointer cannot point to a function with a closure), we cannot pass the function as a parameter to a function, and cannot create a function without a name. "Functions are the first citizens" mean that functions should not be discriminated against ". Functions should have the same status as other types. Of course, there are not many languages for the first citizen to strictly satisfy the function. C # does not support function creation within the function until 7. However, for functional programming, a function requires at least "power", including creating a function literal without a name (namely an anonymous function or Lambda expression) and passing the function as a parameter to other parameters.

I believe you have used Linq. Linq is a typical example of using functions as the first citizen. In functional programming, we dig deep into functions as the value of first citizens.

Related Article

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.