Functional programming (1) Understanding "programming paradigm" and "function"

 

Programming paradigm

 

  A programming paradigm refers to the ideas and perspectives in which we write programs to solve problems. It provides but also determines the programmer's view of the operation of the program. There are many programming paradigms in computer programming, such as imperative programming, declarative programming, object-oriented programming, structured programming, etc. Among them, the object-oriented programming paradigm believes that the program is composed of a series of interacting objects, while the structured programming paradigm believes that the program is composed of subroutines, code blocks, for loops, and while loops. The following mainly describes the imperative programming paradigm and the declarative programming paradigm that this article will talk about.

 

1) Imperative programming:

 

     Emphasizes that the program code simulates the computer running process, and emphasizes "what to do first" and "what to do next". If we want to calculate "2*3+1", we first calculate 2*3 and store it in a temporary variable when we write the code, and then calculate the sum of the temporary variable and 1. Imperative programming is the current mainstream programming paradigm, and almost all the code we write belongs to the imperative programming paradigm.

 

2) Declarative programming (Declarative):

 

     Emphasizing that program code simulates the computing process of the human brain, emphasizing "what is ultimately needed", compared to the imperative programming paradigm, it pays more attention to the result rather than the process. The declarative programming paradigm is closer to human thinking, and its thinking level is higher than imperative programming.

 

The following diagram shows the difference between imperative programming paradigm and declarative programming paradigm:

 


figure 1

 

         Note: Not all programming paradigms are antagonistic, and many paradigms are divided from different perspectives. For example, the object-oriented programming paradigm also belongs to the imperative programming paradigm. Of course, the "imperative programming paradigm" and "declarative programming paradigm" discussed in this article are opposites.

 

 

 

declarative programming paradigm 

 

  There are two common (most common) declarative programming paradigms:

 

1) Domain Specific Language (DSL):

 

  The name is unfamiliar, but we use it a lot. Such as SQL, CSS and regular expressions and so on. These languages ​​only work in specific domains, and when using these languages, most of the time we are writing "statements, declarations" statements. For example, "select * from tb", we only care about the result we want, not the specific implementation.

 

2) Functional Programming (FP):

 

  Functional programming is the focus of our discussion. Since it belongs to the declarative programming paradigm, it should also emphasize the result (What) rather than the process (How). Yes, functional programming is different from common imperative programming. It does not care about the specific implementation process of the computer, but only focuses on the problem results.

 

 

 

Functional Program:

 

  There are many explanations of "functional programming" on the Internet, but most of them are vague and abstract. The explanation of functional programming on Wikipedia is "In computer science, functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data", which translates into Chinese as "Functional programming is a programming paradigm. paradigm, which treats computer operations as the computation of functions in mathematics and avoids the concept of states and variables". What does this mean? Many articles explain several features of functional programming, such as "functions are first citizens", "higher order functions", "no state", "no side effects" "Side-Effect", "Ease of Parallel Development", and "Lazy Evaluation", etc. But I think these are just the features or advantages of functional programming, and do not substantially explain the difference between "functional programming" and ordinary imperative programming. I think in order to understand functional programming, you must first understand the concept of "function". Yes, although we think we are more familiar with "functions" (or "methods", this article does not distinguish the difference between the two), but are we really familiar with them?

 

 

Programming and math functions:

 

     The first time we understood the concept of "function" should be when we were in middle school, "y=x+1" was a straight line in the plane coordinate system, and later (don't know which grade) learned quadratic functions, "y=x ^2+2*x+1" is a parabola in the plane coordinate system. At that time, when learning functions, I knew the following knowledge points:

 

1) A function is a kind of mapping. After the independent variable is transformed through a mapping relationship, the dependent variable (function value) is obtained;

 

2) For each independent variable, there can be, have and only one dependent variable corresponding to it, which is the certainty of the function. That is, given an independent variable, the function value is unique at any time;

 

Then, after learning programming in college (I started learning programming in college), we encountered "function" in the program again, which is very familiar. But how does it relate to functions in mathematics? That is, are mathematical ideas related to our programming ideas? If we look at the code we currently write in C#, Java, C++, etc., they are almost irrelevant, because the functions in our program can have no parameters ("arguments" in mathematical functions), or no return values ​​(the "arguments" in mathematical functions) Dependent variable), even if a function has a return value, given the parameters, the result may be different each time the function is called. None of the above can satisfy the concept of a mathematical function. In fact, the phenomenon that "the two functions are almost irrelevant" is easy to understand. Mathematics describes the human thinking process, and the program code we (most of us) write describes the computer running process. There have long been communication barriers between mathematicians and programmers, such as the following picture:

 

 


figure 2

 

As shown in the figure above, the expression "X=X+1" is almost untenable from a mathematical point of view. If anyone who has not learned programming looks at this expression, TA will think you wrote it. It's wrong, they only recognize "Y=X+1". The reason is very simple, in a program, a symbol can represent a variable, and a variable represents a memory unit where the value can be rewritten (assigned); in mathematics, a symbol is always just a symbol, and the equals sign "=" both sides represent Equivalence relationship, "Y=X+1" means that Y and X+1 are equivalent, and Y is only a substitute for X+1.

 

  The same goes for functions. Functions in mathematics only describe a "mapping relationship", given an independent variable, we can get a dependent variable, and that's it. The function in the program more often plays a "functional" role, which can complete the specified task. Of course, if a function in the program contains parameters and can return a value, then it can fully simulate a mathematical function. Let's write a delegate in C# that represents a unary function in math:

public delegate double Function1X(double x);

 

As shown in the above code, the delegate signature contains a double type parameter and returns a double type return value. "f(x)=x^2+2*x+1" in mathematics can be written in C# as the following function:

public double f(double x) {
     return Math.Pow(x,2) + 2*x + 1;
}

The value of the function f(x) at x=2 calls the code: f(2);. Or use a lambda expression:

 

x => Math.Pow(x,2) + 2*x + 1;

 

The function in the program receives a double type parameter, and after mapping, returns a double type return value, which corresponds to "f(x)=x^2 + 2*x +1". So how is the binary function in the mathematical function represented in the program? Very simple, a binary function contains two arguments, we only need to define two parameters for the function in the program:

public delegate double Function2XY(double x,double y);

 

As shown in the above code, the delegate signature contains two double type parameters and returns a double type return value.

 

  As can be seen from the above introduction, if the functions in the program are limited, then it can simulate functions in mathematics:

 

1) Each function must contain input parameters (as arguments);

 

2) Each function must have a return value (as a dependent variable);

 

3) Whenever a function is called with given parameters, the return value must be consistent.

 

The third restriction above is to satisfy the "determinism" of functions, which requires that functions in the program cannot depend on external factors during execution, and do not affect the external environment. In other words, it is isolated from the outside world during execution. We call a function that satisfies the above conditions a "Pure Function". There is only one channel for pure functions to interact with the outside world - incoming parameters and return values. Pure functions also do not read/change global variables, no IO operations, etc.



 image 3

 

Pure functions are the basis for program code to simulate mathematical functions. In theory, in functional programming, while functions are the first citizens, all functions should also belong to "pure functions". At this point, let's go back and look at the explanation of "functional programming" on Wikipedia: functional programming is a programming paradigm that treats computer operations as the computation of functions in mathematics, and avoids state and variables. concept. Obviously, functional programming is closer to mathematical checking, using a normal mathematical thinking to solve problems.

 

         Note: Functional programming is based on "Lambda Calculus", which does not belong to the category of "Turing Machine" theory. I didn't figure out the lambda check calculation, so I didn't mention it in detail in this article. It's no accident that seeing Lambdas easily reminds us of Lambda expressions introduced in C# 3.0. C# 3.0 began to support "functional programming", which will be covered in a later article.

 

The article is taken from: http://blog.csdn.net/vonsdite/article/details/76796557

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327089696&siteId=291194637