This course has been updated! We now recommend you take the Functional-Light JavaScript, v3 course.
Transcript from the "Questions on Immutability" Lesson
[00:00:00]
>> [MUSIC]
[00:00:04]
>> Kyle Simpson: So if C and W both pointed to the same array, and you froze W, Z would also be frozen. The contents of Z, right? So Z and-
>> Speaker 2: [CROSSTALK]
>> Kyle Simpson: If you had line 11, const w = Object.freeze, and then on line 11.5, you said Z = W.
[00:00:24] So what you're asking.
>> Speaker 2: If you say w = z and then you freeze w-
>> Kyle Simpson: If line 11 said const w = Object.freeze Z, okay, is that the question?
>> Speaker 2: Yeah.
>> Kyle Simpson: The answer to that question is all about references. Z is simply a reference to the array so you would be taking a reference to the array, passing in an object.freeze, it would be making a change to the actual array and now z and w would be constant references to the same array which now had been frozen.
[00:00:55]
>> Speaker 2: Okay. So z would be frozen also?
>> Kyle Simpson: It's not appropriate to think of it as being frozen also cuz there's only one.
>> Speaker 2: Okay.
>> Kyle Simpson: What we're saying is that we've made that change at a distance in a sense, we've made it in line 11 and affected the value that we saw on line 7.
[00:01:10] Okay? Yes?
>> Speaker 3: I think you just answered this a minute ago, but I understand the concept of 7 and 9, but would you ever do 9 except by accident?
>> Kyle Simpson: Absolutely. You know where this happens the most? When somebody says z.length = 0. The question was would line 9 ever happen intentionally?
[00:01:34] Not in that exact representation, where I'm changing one of the values, although that can happen, but what would happen is when somebody tried to empty out your array, you send in an array and somebody said .length=0, now they've mutated the contents of the array to empty it out and maybe they then started adding more stuff to it.
[00:01:53] And they thought, I'm working on my own copy of an array and they weren't, they were working on your array, so absolutely. It's one of the hazards of having references to values is when you pass a reference to someone, you're giving them the keys to the kingdom. Yes.
[00:02:11]
>> Speaker 4: They asked, so object.freeze does not return a copy of the object?
>> Kyle Simpson: It does not, it returns the object itself having now been frozen.
>> Speaker 5: Is there a way to unfreeze that or something?
>> Kyle Simpson: Is there a way to unfreeze objects? You cannot unfreeze an object, but there are multiple levels of freezing.
[00:02:34] This is a little bit further than we're gonna get into, but freeze is like the top level. It's like a permanent sort of irrevocable thing. But there are other things that you can do to set them all as read-only and things like that, and those are undoable. But freeze is sort of the [SOUND] yeah.
[00:02:58]
>> Kyle Simpson: All right, fantastic questions. Now, the other thing that we mean about immutability and this is is the much more important thing to take away from a functional programming perspective. What we mean about immutability is actually a discipline, which is that whatever values we're given, we choose not to change them.
[00:03:17] Whether or not the value itself is actually unchangeable is not really the point. The point really is that we choose not to change it. If we chose to change it and it was immutable, like it was frozen, we'd get an error. If we chose to change and it wasn't, we'd create a side effect so in either case, we don't wanna do it.
[00:03:40] So we say, I'm going to take somebody's value, like an array, and I'm going to not change it but instead produce either a copy of it or produce my own set of values. I'm not going to mutate in place. That's really what a functional programmer is more talking about with immutability.
[00:03:58] Not a characteristic of the value itself but a characteristic of how we choose to use the value, what we choose and choose not to do. In a functional programming language, they don't let you do it. JavaScript lets you do it, unless it's been frozen, but we can still be functional programmers in a sense that we choose not to mutate it.
[00:04:15] Okay? So, let's illustrate that. What if I had a function like doubleThemMutable, okay? It changes the array in place. You notice I passed an array 3, 4, 5, I called doubleThemMutable, and it's actually changing the array in place, doubling all of those values. We could see why this is, this would also be considered an impure function, cuz it's having a side effect on the outside world.
[00:04:43] Not by lexical side effect, but by reference side effect because we passed in a reference. It's able to make a change to a value that's actually not entirely within itself. So this is an impure function in that sense. We're making a change on the outside world. You've probably written hundreds of functions like this.
[00:05:02] This is extremely common. So I'm not saying it's bad, but I'm saying it's impure. It doesn't match with the principles of functional programming. And to whatever extent that we're trying to use functional programming, notions of immutability are things that we wanna pay very close attention to. It's one of the core key concepts, okay?
[00:05:19] So, how could we change this to do the same action but to do it in an immutable way? That is to produce another value, another list rather than changing the list in place. So my superly, awesomely named function doubleThemImmutable. You notice that the main thing here is that I'm setting these values into a new list array, an entirely separate array.
[00:05:46] Has the same number of values in it but when I return it back on line 12, arr is still the original untouched array. It does not matter in this program whether array was actually immutable. What matters is that I use the principle of immutability not to change arr.
[00:06:08] Very subtle but very, very important difference. So one of the chatroom questions was, Are arrays passed as references? Yes. So the way JavaScript does it, and this is actually covered in one of my other workshops, but the way JavaScript does it is, all simple primitives, that's the null, undefined, billion, string and number.
[00:06:29] Those five simple primitives, those are always held by value, that means a variable holds that value itself, and that means assignments are by value copy. Meaning the value itself is copied. So X = 2, Y = X, Y got a copy of 2 in that. Non-simple primitives, non-primitives, like the object, the array, the function, those are always held by reference, meaning the variable doesn't hold the value itself, but it only holds the reference.
[00:06:59] And therefore assignments are by what we call reference copy. So if I say y = in an array, and then I say z = y, I didn't copy the array but I copied a reference to the array such that there are now two separate references to the same array.
[00:07:18] So if that's true of assignment, then all we need to do to answer the question about array is being passed by reference is to say passing an argument is the same thing as assigning it to a parameter. So all assignments happen by reference copy for reference held values.
[00:07:33] They happen by value copy for value held values. And there's no other way to change that. There's no operators or anything. It's just simply an intrinsic nature of how the values are held based on what gets copied. So, bottomline, yes, arrays are pass by reference but actually reference copy is really the best way to say it.
[00:07:54] There are languages where by reference means different things so I try to make sure we're clear on it, what JavaScript, its value copy versus reference copy. Okay, any other questions? There were some questions about people not seeing it throw errors or whatever. So, not seeing object.freeze when we're talking about immutability.
[00:08:15] So, it's important to note that in non-strict mode, which is the default, in non-strict mode, it will not throw an error, it will just simply ignore what you did. In strict mode, it will actually throw an error. So, if you're not in strict mode, you're not gonna be able to see it.
[00:08:30] And by the way, if you're programming at the console in your browser, turning on strict mode in the console statement in your browser is not as easy as you might think. You're gonna have to wrap everything in an iffy, and put use strict in it. It's not as simple as putting it on the first line.
[00:08:44] It's really annoying. The consoles don't work like real JavaScript environments, so. Pardon me. So be careful with your strict versus non-strict if you're trying to learn stuff about how the errors are thrown in those immutability cases.