I’m here to chat with you today. I think it’s a very dreamy concept. Functional Programming is another word you may hear more often , called oriented programming.
Hereinafter, we refer to it as FP and OOP. You can understand that FP is two different programming styles from OOP. Paradigm is called Paradigm in Chinese .
But I think this translation is not very accurate. I think it also has a concept or a pattern . In short, I think it is difficult to find a direct corresponding word in Chinese.
FP and OOP can be imagined as two ends of the imaging spectrum. When you want to write a program When solving a problem, you can choose to use the OP method to solve it , or you can choose to use the functional programming method to solve it. It may be too abstract to say it directly , so let’s take an example directly.
Suppose we want to implement an elevator . Its function is very simple. The function of going up to the first floor and going to the next floor.
If we use op , we usually do this . Use a class to encapsulate the behavior and state of the elevator, that is, the floor it is on. When using the elevator, we can use it like this If you use FP , we will write it like this .
Use function to express the action and update the state of the elevator. When using the elevator , we will use it like this. If you are a person who is used to OOP, you may think at this time, it seems that the OOP writing method is more Easy to read.
What are the benefits of using FP? Let’s take a look at the code of FP. You can stop and look for it.
You should find that there is something that has not changed from the beginning to the end . That’s right, the initialState we declared at the beginning does not exist after the entire program is executed. It has been modified.
Our goUp and goDown methods will not change the value of the input , but will directly generate a new state and then return . This is a very important feature of functional programming . Immutability means that all variables cannot be changed once they are declared.
Modify If you have never been in touch with the concept of functional programming, you should have a lot of ideas when you hear this . Wait a minute, aren’t variables just for changing? Why do I need to change the value of the initial stey every time a new state is generated?
Why do you need to generate a new state for the entire state? If you find it strange that FP has another feature, you may find it even more strange that FP does not use while or for loops , but encourages the use of recursion . Programming languages like Haskell are very strict.
It’s a functional language that doesn’t even let you use loops . You can’t use it even if you want to. If you hear functional programming for the first time , you might think it’s The concept completely subverts your past understanding of programming .
You may even think that writing code like this is more difficult to understand . However, these limitations and design concepts have their benefits. There are too many things to say about FP , and it is impossible to cover it with only one video.
But today’s video I will try my best to answer all the above questions . The goal is to become an entry point for everyone to understand FP. In this video, I will first introduce the very important basic concepts in FP.
After watching it , you will understand what FP really wants to achieve. What ? Then there are some questions that you will have when you first come into contact with the skin .
Next, I will talk about the comparison between functional programming and OOP . Finally , I plan to share my learning process of functional programming. To understand functional programming , the first concept you need to understand It is pure function.
Pure function is actually a kind of function , but it must meet certain restrictions . This restriction is that as long as you give it the same input, it will give you the same output , and this function cannot have any side effects, such as its function. Return only depends on its input , so it belongs to a pure function , and this function will be affected by variables outside the function , so it does not belong to a pure function .
Side effect means to move to any function scope, that is, outside the scope. State For example, if you change the value of a global variable , or you print something on the screen or access a database, these operations are considered side effect pure function. The benefits of pure function are very obvious.
Its result is predictable . What input you give it ? The corresponding output will not be affected by any external factors, which makes unit testing very easy , because it does not have any external dependencies , and one of the core spirits of functional programs is to try to make all functions pure .
Why do you say that as much as possible ? It is because the program in the real world is unlikely to be completely pure. For example, you want to access the database or print the output to the screen.
These actions are considered side effects and will cause your direction to become impure (impure) , but these actions are also It is necessary , which makes it almost impossible to write a useful and completely pure program. So what is the solution of functional programming to this problem? It is to use the monad to push the impure part to the boundary of the program and let the core of the program The heart part is kept pure.
Specifically , how is it done ? And what is a monad because it is beyond the scope of this video , so I will introduce it to you in a later video. Next , I will introduce the concept of immutability that I mentioned earlier.
Chinese means immutability. I think immutability is a stricter concept than pure function. You can imagine that if I have a function that looks like this, can you see what the value of arr3 will be when it finishes executing?
It should be possible. I found out that as long as you don’t look at the program in the middle , you have no way to determine where arr3 has been changed . At least here , I have not changed the values of arr1 and arr2 to produce side effects.
If I change the values of those inputs in my function, it will change. It is even more frightening. From this example, we can see that as long as your variable value can be changed, it will make it difficult for you to be sure where the variable you declared has been changed, especially in your for loop , the longer the code The more time or functions you have, the more you will feel .
If all variables cannot be changed after they are declared , can this problem be solved? That’s right , this is why FP puts special emphasis on it. Immutability is because as long as you cannot modify all the variables after they are declared , the code will be easier to understand and less likely to have bugs.
In fact, some default behaviors that comply with the FP programming language are to make the variable default immutable (unmodifiable) ) These languages will deliberately make it troublesome to modify variables, so that you do not modify variables as much as possible , so that you try to abide by the principle of immutability. For example, in rust , if you want to make a variable modifiable, you must add mut This word can only be used if it is a pure functional language like haskell , it will be more troublesome. General variables are not allowed to be modified at all.
You must use the monad mentioned above to be able to understand the concept of immutable . You can go back and talk about why FP avoids using for loop or while loop to write programs. If you have been writing programs for a while , you should have such an intuition .
The nature of the loop is actually very mutable . As long as there is a loop , it is usually accompanied by Mutation is the modification of variables. If you don’t believe me, let’s look at some examples .
Look back at the loops you wrote in the past, and you will find that the things you do in the loops can fall into the following two types. The first is to modify the loops. External variables are mutations .
The second type is to generate side effects. For example, to print the value of something, you will find that the loop seems to be either doing mutations or generating side effects. You should feel that we can almost sum up a rule .
Go back to variables It is only useful if it is mutable. When you want to achieve immutability, the loop is almost useless because you can’t do anything in the loop. After understanding the above prerequisites , you will find that functional programming does not use It is very reasonable to loop back and use recursion to complete the iterative function .
When a function is called, it usually generates a new context in the call stack , which can effectively limit the scope of variables that can be read or modified , and it is easier to maintain In the case of immutability, do what you would have done using a loop . For example, in the example on the left, we use for to return and add up the variables in an array . We must modify the value of the result variable , that is, we must use mutation to achieve it .
But If I use recursion, I don't need to modify the value of any variable at all to add up the value of the array . Of course, this is just an example for illustration . It is not a crime to use a mutable variable in such a small functional.
The trouble caused by using mutable variables will only start to appear when your code becomes very long or more complicated. However, it is not convenient to always use recursion to write functions when writing code, so usually we will Use functions such as reduce map filter to replace and recurse to increase readability. For example, this example is to use reduce to add up the value of an array.
It becomes an immutability pure function and does not use a loop. After these conditions , you will Start to discover that your way of writing programs will gradually change from imperative to declarative . Now everyone may be wondering what the hell is imperative and declarative, so I will use an example that everyone is very familiar with , such as assembly language, and you will tell the computer step by step.
How to change variables or even register values and then calculate the results is very biased toward imperative programming , while declarative writing is to directly write what you want instead of telling the computer how to do it step by step . Everyone is familiar with it. SQL syntax means that you directly specify what you want instead of telling the computer how to calculate this value, so it is very biased towards declarative , like html is also a very declarative example.
Let me give a simple example. Suppose I want to put the value in an array 123456 To get the even numbers out , I can use very declarative writing or very imparative writing. You will find that using declarative we are directly telling the computer what the result we want is , while the imperative is telling the computer what to do step by step.
Execute to produce the result we want . Many people may have some misunderstandings about the meaning of declarative, and they will think "isn't it just splitting the code into functions to make the code shorter? " Or isn't declarative just using built-in functions to make the code shorter?
That’s all, but these are not the essence of declarative. The point of the word declarative is not the length of the code, but the point is that your code can be simplified to a value or an expression , just like a mathematical expression can be continuously simplified. Let’s get back Looking at the example just now, you will find that the large string behind return can be directly simplified to the final result without any intermediate execution steps .
If my input is 123456, the return value itself is 246, which means that this string of expansion itself represents me. The result of using impe In the way of writing rative, you will find that there are intermediate steps to tell the computer how to do calculations , and because of these intermediate steps , the entire calculation process cannot be simplified into an expression, so the original intention of declaration is not abstract, nor is it to split code into functions It’s not to make the code shorter. Those are just by-products .
Some people may be curious about whether I used the inner key filter or to achieve the declarative effect . What if I don’t have a filter to use? I don’t need that function.
Can I still do declarative? In fact, I can write this function in a recursive way . You will find that there are no intermediate steps in it , and no variables are created .
I just return different values according to the input because there is no Any intermediate steps, this function can be simplified to a value, don’t you believe it, let ’s try it directly , because if can be replaced by ternary expression , so I can change the above code to this, you will find that this function is simplified to direct return a value So this is a very declarative way of writing. Of course , this is just an example to help you understand the conceptual difference between declarative and imperative. It does not mean that we will write code like this when we actually write functional programming .
Above, I only introduced the most basic of FP. But do n’t think that FP is only as simple as this . There are still many details that can be explored in practice .
FP also has its own design patterns like OOP , including functors applicatives monads, etc. Because I really can’t finish it in detail , so I will introduce these concepts in another video . If you want me to make more FP-related videos, you must give me a like and leave a message to support him.
He is usually the first to hear the concept of immutability. Everyone will intuitively have a question , that is, will immutability cause performance problems? In order to satisfy the immutability, every time we want to modify a variable , we need to generate a new copy.
Variables need to be copied continuously, which makes the performance poor . If you don’t use loop and then use recursion, doesn’t it mean that your call stack will be stacked higher and higher , taking up a lot of memory? Here I share two reasons to explain these It’s not a big problem.
This is actually to integrate some arguments I saw on the Internet and then integrate my own understanding , so please correct me if there are mistakes . The first point is that FP is a relatively high level concept , so you can compare low level things Let the compiler handle it. The second point is that it is very worthwhile to exchange a little performance for a clean program.
Let ’s start with the first point . Methods and programs are a high-level way of writing programs. Here we say high Level does not mean that it is more advanced or superior, but refers to the degree of abstraction.
From the lowest level , it may be a signal composed of 0 and 1. C language may be much higher, Java may be a little higher, and Haskell this In this way, the language of the building is at a higher level, and the higher the level you go , you will find that your focus will be on the overall logic without worrying about some detailed low-level control operations such as memory allocation and release. Why you can ignore these low level things because you leave these things to the compiler and the compiler will compile your high level program into a low level binary file like this The computer can execute it.
During the compilation process, the compiler can also help you to optimize the program. For example, in Haskell , if I have a list of 123 called foo, I want to add the first value to the haskell compier He does not copy the entire list , but he only changes the head part , but the tail part can still be shared , and the recursive part also has a thing called tail recursion, which is also a very important concept in FP . Simply put That is, the compiler can automatically optimize some recursive methods to reduce memory usage .
I won’t go into details here. I will make another video to introduce to you in the future . In short, the point is that the compiler can help you do some optimization to some extent.
Therefore, the performance loss caused by immutability is not as serious as imagined . Then we will talk about the second point , which is to exchange a little performance for a clean program . You can think of immutability as a kind of tradeoff.
In order to achieve immutability, you must sacrifice a little bit. A little bit of performance , but on the other hand , you only sacrificed a little bit of performance in exchange for a very clean and easy-to-understand program . This is a very worthwhile tradeoff because most of the programs we write in the real world are not worse than this little bit of performance .
Instead, they are mutable. The debugging and maintenance costs brought by variables are very large. Combining the above two points, we can conclude that in most cases, immutability does not cause too much performance problem.
The benefits it brings must outweigh the disadvantages of FP Is it a more advanced concept than OOP? I believe that some people will start to have these questions after coming into contact with FP. This is also a topic that is often debated on the Internet .
This is also a question that I would like to explore . Share it here Let me give you my personal opinion. First of all, we need to clarify a concept .
FP and OOP are two of many programming paradigms, so they are not completely opposite . If you spend some time on the Internet and read the discussions on various forums, they are different. There is a suitable place , or you need to wait for both .
After a while, you will find that many people think that no one method is better , so you can’t find a conclusion. I think this kind of statement cannot be said to be wrong. But I think this conclusion is not satisfactory enough , so I still want to continue to explore and find my own answer in the future.
Here are three points of my own opinion . The first point is that when you meet some requirements and you want to write programs from scratch , you can Use FP thinking to design the program architecture , or use OOP thinking to design . The two methods will eventually produce very different products .
Indeed, OOP can be mixed with FP elements. FP may also add some object-oriented things . No totally conflicting but I think that in the initial design, you still have to choose whether to use FP thinking or OOP thinking to conceive the entire architecture , so to some extent you still have to make a choice between them , and I spent some time reading a lot on the Internet.
The result of people's arguments is that I didn't get an answer , so I still have to find out by myself. After trying both methods, I got the answer from my own experience. The second point is that because OOP is relatively mainstream, in many cases we are very I am used to using OOP by default , but is OOP really a more suitable method in those situations?
I think this is still worth thinking about. Some problems that people used to use OOP to deal with in the past may be well solved by using FP . There are relatively few people doing this now , and if FP and OOP have their own suitable application scenarios , we can also discuss in depth which concept is more suitable for which application .
After all, after all, the style of writing programs has to some extent . the subjective component , so even if everyone did the same experiment, You may not necessarily get the same conclusion. Some people may think that OOP is better , and some people just prefer FP, so in the future, I still want to do various experiments by myself to get my own conclusion .
Having said so much , I actually have no intention to make a decision here. A conclusion I don’t think either FP or OOP must be superior. Maybe there will be a new paradigm in the future that can integrate the benefits of both.
What I want to express is that I am not satisfied with each of them. There are suitable applications For such an answer , I want to explore by myself which method is more suitable under what circumstances. At this stage , I have a deep understanding of OOP and FP and experience.
I think it is not enough for the next conclusion , so I will continue to think about it in the future. And explore this issue. If I have new ideas, I will come back to share with you .
Everyone may have different preferences and experiences. So if you have any opinions on this topic , please leave a comment below to share your opinions. OK, today’s branch The content of the video is a brief introduction to some basic concepts in the FC world .
I haven’t discussed many things in depth because this video is mainly to let people who don’t know the concept of AP know about it. If you are interested, you can do further research by yourself. If you already know about FP , take it as cool.
In fact , I have only come into contact with functional programming very recently . I am still learning, so the content of the next video will be a little easier . I will share my experience with you.
How did you get in touch with functional programming and start learning the whole process , as well as future study plans? If you are interested in functional programming or want to know how I can learn a programming language from scratch , remember to subscribe to my channel and turn on the little bell so you won’t miss it.