Former article juejin. Cn/post / 694203… Subsequent juejin. Cn/post / 694906…
Day 6: Data is immutable
Student: Good morning, here I am again. Yesterday we talked about closures. What are we talking about today?
First, let’s talk about the execution process of the function.
let v0 = 'global v0'
let f1 = (p1)=>{
let v1 = 'v1'
return [v0, v1, p1]
}
f1('p1')
Copy the code
What value does f1(‘p1’) output?
Student: It’s not a monk’s head lice — it’s obvious, output [v0, v1, P1]
Fang: How did the results come about?
Student: When f1 executes, it reads P1 and v1 from the current scope, v0 from the global scope, and then puts them together
Fang: Yes, let me draw a picture to illustrate:
- Env0 = {v0, f1};
- When executing f1, env1 = {v1, p1} is created;
- When return [v0, v1, p1] is executed, env1->env0 is searched, the final array is calculated and returned.
Student: Well, no problem.
Now let’s make the code a little more complicated:
let v0 = 'global v0'
let f1 = (p1)=>{
let v1 = 'v1'
let f2 = (p2) => {
let v2 = 'v2'
return [v0, v1, v2, p1, p2]
}
return f2('p2')
}
f1('p1')
Copy the code
Add f2 to f1 and return f2()
Student: Oh, you added a layer of function calls
The current picture should look like this:
- Env0 = {v0, f1};
- When executing f1, env1 = {v1, p1, f2} is created;
- When f2 is executed, env2 = {v2, p2} is created.
- When return [v0, v1, v2, p1, p2] is executed, the array is calculated and returned in the order env2 ->env1->env0.
See a pattern?
Student: When a function is executed, always look for values in the env chain from near to far?
Fang: That’s right. So far our code has never assigned, so let’s try assigning. This is the first time we’ve used “assign” in days:
let v0 = 100
let f1 = (p1)=>{
v0 = v0 - p1
return v0
}
f1(1)
Copy the code
Environmental model:
Student: The value of the global variable v0 is changed to v0-1. Let v0 = 100 is not an assignment.
Fang: Well, we agree that let v0 = 100 is called “initialization” or “binding” and v0 = v0-p1 is called “assignment”.
Student: I call them first assignment and second assignment…
Fong: Do it my way
Student: Ok, listen to you…
The essence of “assignment” is to change the environment (ENv2, ENv1, ENV0), also means “variable data”.
Student: Fong, you finally started to answer the question “what is immutable data?” I thought you had forgotten it long ago
Fang: No, let’s see what’s wrong with “assignment”
Student: What’s wrong with the second assignment?
For the first question, the meaning of the function has changed:
F1 (1) // is 99, f1(1) // is 98, f1(1) // is 97Copy the code
For the same input parameter 1, the output of f1 keeps changing
Student: So what? Isn’t that normal?
Fang: This causes the “substitution method” to no longer work, because when you substitute v0, you can’t be sure whether v0 is 100, 99 or 98:
F1 (1) => v0 = v0-P1 => v0 = 100-1 // v0 100 => v0 = 99 F1 (1) => v0 = v0-p1 => v0 = 99-1 // v0 99 => v0 = 9 f1(1) => v0 = v0-p1 => v0 = 98-1 // v0Copy the code
You need to know how many times you are currently calling f1 to determine the value of v0.
If v0 can be assigned by other functions, it doesn’t help that you simply remember how many times f1 was called. You need to know the order in which all functions were called to determine the value of v0!
Student: It seems to be, so if you can’t use the substitution method, you don’t have to use it. Is it a big deal?
The introduction of “assignment” may seem like a loss of “substitution” in favor of “environment model”, but it actually cuts the link between function and mathematics.
Student: What do you mean?
F (x) = x – 1 always returns the same value for the same x.
Student: To tell you the truth… Sever the link between programming and mathematics… It’s good, too. I’m bad at math, so it’s calmer
Fang: Well, the first downside of variable data doesn’t seem to convince you. Let’s look at the second issue — data sharing:
Const options = [{data:1}, {data:2}] initEngine(options) console.log(options) ____ line 4 _____Copy the code
If you do not “disable assignment”, no one knows whether initEngine(Options) will modify the contents of options. Also, if I change options in line 4, it will affect Engine internally.
Student: So make a copy of options and pass it to initEngine…
Fang: How? Shallow copy doesn’t work, you have to do deep copy. Can you write deep copy? Famous interview question
Student: Oh, I’m not sure I can write it right away… I usually use libraries. So does “data mutable” lead to deep copy?
Fang: No, it should be said that “assignment” makes data sharing troublesome, you can’t trust others not to change your data, and others can’t trust you:
- Or we can rely on everyone consciously and agree that no one changes options (I can only say good luck to you);
- Either make a deep copy before sending it to someone else, or make a deep copy of someone else’s data as well…
With “disabled assignment” (that is, immutable data), all data can be shared: you can pass data to any function without worrying that someone else has changed your data, or that you have accidentally changed someone else’s data.
Student: It kind of convinces me to support “data immutable”. Currently I’m on a team that relies on convention, but I do have situations where options I passed to others were changed.
Fang: At present, two advantages of “immutable data” tell you:
- Variable data will lead to the “substitution method” is not available, the function and mathematics no longer related; Immutable data is the opposite
- Data variability makes it difficult to share data; Immutable data is the opposite
Student: Are there any other advantages?
Fang: Yes, there are, but examples are too difficult to construct and not universal. For example, functional programming claims a natural advantage for handling concurrent tasks, but I haven’t found overwhelming evidence.
Student: So what does the Internet mean that functional programming has “no side effects”?
No side effects means that functions in functional programming do not modify their own env, nor do they modify objects passed in as arguments, only their own local variables.
Student: That doesn’t sound like much…
Fang: Indeed, this means that any JS modification of window.document.title is a “side effect”.
Student: What if I just want to modify window.document.title?
Fong: If you must have side effects, the functional way to deal with them is to create a special area for side effects, like smoking rooms in public places. For example, the React functional component suggests you write all side effects in use effects.
Student: Oh, so how does Haskell do it?
Fang: It’s a long story. Let’s talk about it next time
Student: I really want to hear this… What is “referential transparency”
Fang: This is useless, too. Quoting transparency is originally a concept in linguistics. For example, “Shanghai” is also called “magic capital”. Replacing “Shanghai” in the sentence with “magic capital” should not change the semantics:
I like Shanghai. I like the Magic capital.Copy the code
If “Shanghai” is changed to “Magic capital” in all sentences without changing the semantics, we say both are “referential transparent”. Unfortunately, changing the word “Shanghai” to “Magic Capital” in the following sentence would change the original meaning:
It's nice at night. The night devils are good to look at.Copy the code
Dota players might think that the second sentence is a compliment to the “Night Demon” hero…
Student: What does “referential transparency” mean in a function?
If f(1) == 99, then changing all 99 in the code to f(1) (or vice versa) should not change the original meaning, which is referential transparency. This requires that f(1) always return 99, not 99 and 98.
Student: What’s the use of that?
Fang: As far as work is concerned, not much…
Student: What about “pure functions”
A pure function means that the return value of this function does not depend on the external environment (the return value does not change if the argument does not change), and the function does not modify the external environment (no side effects). If you do need to modify the external environment, do so in a specific area.
Student: I feel like you’re talking on wheels… It all seems to say “data is immutable”. And finally, is “data immutable” the same thing as “functional programming”?
Square: not equivalent, functional programming is actually want to use the method of mathematical methods or semiotics to write reliable program, in order to make the code as much as possible with mathematics more fit, then let our code as simple as possible, abandoning quadratic assignment is a very good choice, this makes our code to reduce dependence on external environment. Therefore, “data immutable” is a very suitable feature for “functional programming”.
Even functions are thus divided, with “pure functional programming” believing that “data immutable” is necessary and “impure functional programming” believing that “data immutable” is not necessary. The former is represented by Haskell and the latter by Lisp.
Student: Then why didn’t you tell me the advantages of immutable data on day one?
Fang: It’s no use. Even if I told you these advantages on the first day, you wouldn’t be convinced
- How can I write code without assigning?
- What if recursive performance is slow?
- How do functions encapsulate data?
And so on. And even now, you don’t see a big advantage in immutable data, do you?
Student: Well, since “data immutable” has no huge advantage, why should I learn “data immutable”?
Fang: We can theoretically analyze how reliable “data immutable” is, but from the practical point of view, the two can achieve the same effect. Even “data mutable” is more suitable for newcomers. So the reason I recommend you learn functional programming with “data immutable” is to broaden your horizons.
Student: Ok, I’ll review what we learned this week. Are you going to talk about it later?
Fang: I want to talk about Monad, but let’s take a break for a few days
Student: Ok, let me know when you have time
Fang: OK
That’s all for now. Please leave a message if you want to hear from Monad.