1. Overview
In the past decade, object-oriented programming has become popular. As a result, in university education, teachers only teach us two programming models, process-oriented and object-oriented.
I don't know. Before the emergence of Object-oriented Thinking, functional programming has been around for decades.
Next, let's review this ancient and modern programming model, let's see what magic means to use this old concept, today, in the 21st century, we have once again taken our field of vision.
2. What is functional programming?
Function programming has been described in detail in Wikipedia.
Let's take a look at the definition of functional programming on the Wiki:
In computer science,Functional ProgrammingIs a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data.
Simply translate, that isFunction programming is a programming model. It regards computer operations as function computing in mathematics and avoids the concept of state and variable..
Next, we will analyze some features of functional programming.
3. Start with concurrency
To put it bluntly, I was the first one who really came into contact with functional programming. to trace back to Erlang programming two years ago, we know that Erlang is a high-concurrency support, function Type with strong fault toleranceProgramming Language.
Because it has been too long and has never been applied in real time, Erlang is just stuck in some perceptual knowledge. In my eyes, Erlang's support for high concurrency lies in two aspects. First,Support for lightweight processes by Erlang(Note that the process here is not equal to the operating system process, but only a unit in Erlang.), second,Is the immutability of variables..
4. immutability of Variables
In Erlang programming, the immutability of variables is described as follows. Erlang is the only language with immutability of variables. I can't remember the specific words. I don't know whether the old man wrote this question or the translator's question. When I wrote a book review for this book, I said:
I disagree with this sentence, not to mention the old lisp, and then to the present, F # has a different perspective on the assignment operation, low people and so on. To put it simply, the final and readonly provided by today's Java and C # support variable immutability, and this unique one seems a little arrogant.
Let's take a look at two paragraphs.ProgramFirst, we have a common program that includes Value assignment:
Class account:
Def _ init _ (self, balance ):
Self. Balance = balance
Def desposit (self, amount ):
Self. Balance = self. Balance + amount
Return self. Balance
Def desposittwice (Self ):
Self. Balance = self. Balance * 2
Return self. Balance
If _ name _ = '_ main __':
Account = Account (100)
Print (account. desposit (10 ))
Print (account. desposittwice ())
There is no problem with this program, but we have considered this situation. Now there are multiple processes running this program at the same time, then the program will be affected by desposit or desposittwice first.
However, if we adopt the following method:
Def makeaccount (balance ):
Global desposit
Global desposittwice
Def desposit (amount ):
Result = balance + amount
Return result
Def desposittwice ():
Result = balance * 2
Return result
Def dispatch (method ):
Return eval (method)
Return dispatch
If _ name _ = '_ main __':
Handler = makeaccount (100)
Print (handler ('destopsit ') (10 ))
Print (handler ('destosittwice ')())
At this time, we will find that no matter how many processes are running, because we have no value assignment operation, it will not affect our final results.
But as you can see, there is no way to maintain the status in this way.
This is what we see in our previous concepts as stateless.
5. Let's look at the rise of functional programming.
Now that we have read the basic features of functional programming, let's think about the reasons behind the rise of functional programming in decades.
For a long time, lisp, or Haskell, represented by functional programming, are mostly applied in universities and laboratories, but rarely in real production environments.
Let's review the great Moore's Law:
1. The number of integrated circuits on an integrated circuit chip doubles every 18 months.
2. The performance of the microprocessor doubles every 18 months, and the price drops by half.
3. The performance of a computer that you can buy at a price of one dollar doubles every 18 months.
Moore's predictions show that the entire information industry is moving forward rapidly. However, in recent years, we can find that Moore's Law has gradually expired, the size of components on the chip cannot be reduced infinitely, which means that the number of electronic components that can be integrated on the chip will reach a limit at a certain time. So when the technology reaches this limit, how can we adapt to the increasing computing needs? The electronic component manufacturer gives the answer: multi-core.
MultipleThe core parallel program design was pushed to the front line, while the inherent defect of imperative programming made the parallel programming model very complex, whether it is a semaphore or a lock concept, make programmers unbearable.
In this way, functional programming finally came out of the lab after several years and came to the real production environment, whether it's the cold Haskell, Erlang, Scala, F #, these are typical examples of successful functional programming.
6. The first type of functional programming
As we know, objects are the first type of object-oriented programming, so are functional programming. functions are the first type of functional programming.
In functional programming, we strive to use functions to express all concepts and complete all operations.
In object-oriented programming, we transmit the object.In functional programming, what we need to do is to pass the function over and over, and this is a term. We call it a high-order function..
Let's look at the application of a higher-order function. Those familiar with JS shouldCodeVery familiar. Let's write a sample code for a filter commonly used in electronic circuits.
Def filt (ARR, func ):
Result = []
For item in arr:
Result. append (func (item ))
Return result
Def myfilter (Ele ):
If ele <0:
Return 0
Return ele
If _ name _ = '_ main __':
Arr = [-5, 3, 5, 11,-45, 32]
Print ('% s' % (filt (ARR, myfilter )))
Oh, I forgot to say, what is a high-order function? Let's define it:
In mathematics and computer science,High-order functionsIs a function that meets at least one of the following conditions:
- Accepts one or more functions as input.
- Output A Function
Then, there is no doubt that the above filter is an application of high-order functions.
In functional programming, a function is the basic unit and the first type. It is almost used as everything, including the simplest calculation, and even the calculation of variables. In functional programming, variables are just a name, not a storage unit. This is the most typical difference between functional programming and traditional imperative programming.
Let's take a look. The variable is just a name. In the above code, we can rewrite the main function as follows:
If _ name _ = '_ main __':
Arr = [-5, 3, 5, 11,-45, 32]
Func = myfilter
Print ('% s' % (filt (ARR, func )))
Of course, we can also streamline the program, using the powerful tools in functional programming, MAP, filter, and reduce:
If _ name _ = '_ main __':
Arr = [-5, 3, 5, 11,-45, 32]
Print ('% s' % (MAP (lambda X: 0 if x <0 else X, arr )))
Does this look more pleasing to the eye?
In this way, we can see that functions are the basic unit of our programming.
7. mathematical nature of functional programming
Forget who said: all problems are ultimately mathematical problems.
Programming has never been difficult. It is nothing more than being careful. With the familiarity of some function class libraries and the accumulation of experience, what is really difficult is how to put a practical problem, convert to a mathematical model. That's why companies like Microsoft and Google attach importance to it.AlgorithmThis is why the mathematical modeling competition is so important in the computer department of the University.
Let us assume that we have already built a mathematical model with our good mathematical and logical thinking. What we need to do next is to develop a mathematical language into a programming language that computers can understand.
Now let's look at the value assignment model we mentioned in section 4. The same function and the same parameter will calculate different results in different scenarios, this is completely impossible in mathematical functions,F (x) = Y, then this function will get the same result in any scenario. This is called the function's certainty.
This is also the incompatibility between the value assignment model and the mathematical model. WhileFunction programming removes the value assignment model, so that the mathematical model and programming model are perfectly unified..
8. abstract nature of functional programming
I believe that every programmer is familiar with the concept of abstraction.
In object-oriented programming, we say,Class is an abstract representation of real things. In my opinion, the greatest role of abstraction lies in the reusability of abstract things.The more specific a thing, the lower its reusability. Therefore, when we create reusable code, classes, and class libraries, in fact, the essence of work is to improve the abstraction of code. Let's talk about it again,What programmers do is to abstract a series of processes into a general process.And then use the code.
In object orientation, we abstract things. In function programming, We are abstracting function methods. The filter in Section 6 has shown us that functions are reusable and replaceable abstract units.
So let's sayThe abstract nature of functional programming is to use functions as an abstract unit and reflect them in the form of code. It is a high-level function..
9. What should I do?
We talked about a lot of functional programming features, but we ignored them. They are all at the ideal level. Let's look back at the variable immutability in section 4. Indeed, let's say, functional programming is stateless, but in our actual situation, the State cannot remain unchanged, and the State must be changed and transmitted, in function programming, we store it in the function parameters and pass it as an accessory to the function.
PS: in Erlang, variables for interaction between processes are implemented by sending and receiving letters in the "Mailbox". In fact, let's think about it. In essence, is variable passed as an accessory!
Let's take a look at an example. Here is an example of the n power of X. Let's write it using traditional imperative programming:
Def expr (x, n ):
Result = 1
For I in range (1, n + 1 ):
Result = Result * x
Return result
If _ name _ = '_ main __':
Print (expr (2, 5 ))
Here, we are always assigning values to the result variable, but we know that the variables in functional programming are immutable, so in order to keep the result state, you need to pass the result as a function parameter to maintain the status:
Def expr (Num, n ):
If n = 0:
Return 1
Return num * expr (Num, n-1)
If _ name _ = '_ main __':
Print (expr (2, 5 ))
Yo, isn't that recursive!
10. Functional Programming and Recursion
Recursion is an important concept of functional programming. loops can be absent, but recursion is indispensable for functional programming.
Here, I have to admit that I do not know how to explain why recursion is so important to functional programming. All I can think of is that recursion gives full play to the power of functions and solves the stateless problem of functional programming. (If you have other comments, please kindly advise)
Recursion is actually an infinite decomposition of big problems until the problem is small enough.
The biggest difference between recursive and loop programming and thinking models is:
The loop describes how to solve the problem.
Recursion is the definition of this problem.
Let's take the Fibonacci series as an example to look at these two programming models.
First, let's talk about our most common recursive model. Here, I don't use dynamic planning for temporary state caching, just to talk about this idea:
Def fib ():
If a = 0 or a = 1:
Return 1
Else:
Return fib (A-2) + fib (A-1)
Recursion is used to describe what is a Fibonacci series, which is defined as a number equal to the sum of the first two items and is known to be fib (0) and FIB (1) equal to 1. The program re-describes the definition in computer language.
Next, let's look at the loop model:
Def fib (n ):
A = 1
B = 1
N = n-1
While n> 0:
Temp =
A = a + B
B = temp
N = n-1
Return B
Here we will describe how to solve the Fibonacci series. What should we do first.
As we can see, recursion is more readable than loops.
However, we cannot ignore the stackoverflow generated by recursion. What about the value assignment model? What do we know is that function programming cannot assign values?
11. tail recursion and pseudo Recursion
Previously we talked about the problems of recursion and loop. How can we solve this problem? function programming throws an answer for us, namely tail recursion.
What is tail recursion, in the most popular words:Is simply calling recursive functions in the last part.Here, we should pay attention to the word "simple.
Let's talk about the principle of tail recursion,In fact, tail recursion is not to maintain the current state of recursive functions, but to pass all the things to be maintained to the next function using parameters, so that the stack space of this call can be automatically cleared.In this case, the occupied stack space is the constant order.
Before looking at the tail recursive code, let's clarify the recursive classification.Recursion is divided into "tree recursion" and "tail recursion". What is tree recursion is to expand the computing process one by one and form a tree-like structure.For example, the recursive solution of the previous Fibonacci series.
Let's take a look at the syntax of Fibonacci tail recursion:
Def fib (A, B, n ):
If n = 0:
Return B
Else:
Return fib (B, A + B, n-1)
It seems a bit difficult to understand here. Let's explain: the numbers a and B passed in are the first two. So every time I push one digit, B becomes the first number, A + B is the second number.
This is tail recursion. In fact, let's think about it. This is not to describe the problem, but to find a solution to the problem. What is the difference between it and the above loop? Let's do a conversion from tail recursion to loop!
Finally, B is returned, so I will first declare that B = 0
To pass in a, I declare that a = 1
Whether to calculate n = 0 or loop while n! = 0
Every time we make a calculation like that, right? I want to swap it with temporary variables. Temp = B; B = a + B; A = temp.
Then, according to this step-by-step conversion, is it the loop code we wrote above?
This tail recursion is essentially a "pseudo recursion ",What do you mean?
Since we can optimize it, for most functional programming language compilers, they also provide optimization for tail recursion, so that tail recursion can be optimized into the form of loop iteration, this prevents stack overflow.
12. Evaluate inertia and Parallelism
The first time I came into contact with the concept of inertia evaluation, I think it is also the most classic example to look at the simplest inertia evaluation in Haskell:
In Haskell, there is a repeat keyword, whose function is to return an infinitely long list, so let's look at it:
Take 10 (repeat 1)
This is the code. If there is no inertia evaluation, I think this process will definitely die there, but the result is normal, and a list with a length of 10 is returned, the values in the list are all 1. This is a typical case of inertia evaluation.
Let's look at a simple piece of code:
Def getresult ():
A = geta () // take a long time
B = getb () // take a long time
C = a + B
The code itself is very simple. In the imperative program design, the compiler (or interpreter) will interpret the code one by one, obtain the values of A and B in order, and then find C.
But from the perspective of parallelism, can we calculate the value of A in parallel with the value of B? That is to say, the compiler realized that a and B didn't need it until the execution of A + B. Then our dual-core processor will naturally play its best role in computing!
This is the greatest power of inertia.
Of course, the value of inertia has the following advantages and disadvantages:
Def test ():
Print ('Please enter a number :')
A = raw_input ()
However, if the code is evaluated with inertia, the first sentence may not be executed before the second sentence.
13. Functional Programming Overview
After reading the features of functional programming, let's look at the application scenarios of functional programming.
1. Mathematical Reasoning
2. Parallel Programs
In general, functional programming is best suited to solving small mathematical problems in the locality. Functional programming should be used as crud to implement traditional WEB programming with strong logic, it is easy.
Just like if Scala is used to completely replace today's Java job, I am afraid the effect will be very bad. But it is no longer appropriate to let Scala write the underlying services.
The most typical C # language is incorporated into a language #. Introduce lambda expressions in C #3.0 and Declarative Programming in C #4.0. Some of us ignore this syntax when we laugh at C # Getting bloated, it brings us not only the traversal of code writing, but also an improvement in programming thinking.
Well, let's forget the implementation mechanism behind Lambda in C #. in C #, it is still in languages that support functional programming more purely, enjoy the joy of functional programming!
Link: http://www.cnblogs.com/kym/archive/2011/03/07/1976519.html