# Staying immutable in a mutable language ## Topic - Apply a copy-on-write discipline to ensure that data is not changed. - Develop copy-on-write operations for arrays and objects. - Make copy-on-write work well for deeply nested data. - In JavaScript you have to do all the work yourself. That’s why it’s convenient to wrap it up with some utility functions that handle everything for you. If you stick with those wrapper functions, you’ll be fine. Sticking with it is why it’s called a discipline. ## Can immutability be applied everywhere? ![](https://i.imgur.com/CvLkQXV.png) The fifth operation is harder, because it is modifying an item inside of a shopping cart. We call that ***nested data***. ## Categorizing operations into reads, writes, or both ### Read - It don’t need any other work. Reads that get information from their arguments are calculations. ### Write - The rest of our operations. They modify the data in some way. These will require a discipline, because we don’t want to modify any of the values that may be in use somewhere else. ### The three steps of the copy-on-write discipline 1. Make a copy. 2. Modify the copy (as much as you want!). 3. Return the copy. ![](https://i.imgur.com/T69kCcQ.png) - Here’s a question. Is add_element_last() a read or a write? - It doesn’t modify the data, and now it returns information, so it must be a read! - We’ve essentially converted a write into a read. ### Converting a write to a read with copy-on-write ![](https://i.imgur.com/mnLYU6J.png) ![](https://i.imgur.com/UhT44Tw.png) ![](https://i.imgur.com/CdprTBQ.png) ### These copy-on-write operations are generalizable ![](https://i.imgur.com/rJojcGi.png) ### What to do if an operation is a read and a write ```javascript var a = [1, 2, 3, 4]; var b = a.shift(); console.log(b); // prints 1 console.log(a); // prints [2, 3, 4] ``` - .shift() returns the first element of the array at the same time as it modifies the array. It’s both a read and a write. 1. Split the function into read and write. 2. Return two values from the function. ![](https://i.imgur.com/qLXHyug.png) ![](https://i.imgur.com/zc6eRkJ.png) ## Javascript Array and Object operations ## Brain Storm <!-- - A lot of important thinking and planning is done with answers to hypothetical questions. Remember, calculations are often used for planning. --> - It may be better to use an object for shipping cart. - It seems like a lot of work to implement immutability. Is it worth it? Can it be easier? ## Reads to immutable data structures are calculations - Reading mutable data is an action. (We could get a different answer each time we read it.) - Writes modify data will make the data mutable. - If there are no writes to a piece of data, it is immutable - If we get rid of all of the writes by converting them to reads, the data won’t ever change after it is created. That means it’s immutable. - Reads to immutable data structures are calculations - Once we do make the data immutable, all of those reads become calculations. - Converting writes to reads makes more code calculations - The more data structures we treat as immutable, the more code we have in calculations and the less we have in actions. ## Applications have state that changes over time - We can keep track of changes over time. We do have that place. It’s the shopping_cart global variable. - We’ll use swapping pattern. This is a very common and powerful pattern in functional programming. Swapping makes it really easy to implement an undo command. >Functional programmers prefer immutable data by default. Only if they find that something is too slow will they optimize for performance with mutable data. Garbage collectors are really fast ## Summary • In functional programming, we want to use immutable data. It is impossible to write calculations on mutable data. • Copy-on-write is a discipline for ensuring our data is immutable. It means we make a copy and modify it instead of modifying the original. • Copy-on-write requires making a shallow copy before modifying the copy, then returning it. It is useful for implementing immutability within code that you control. • We can implement copy-on-write versions of the basic array and object operations to reduce the amount of boilerplate we have to write. ## Up Next We need a way of exchanging data with that code without it changing our data. In the next chapter, we will learn another discipline called defensive copying.