# State, Mutation, and Side Effects

Computer Science I · Programming II · https://tryals.app/learn/computer-science-i/state-mutation-and-side-effects

## State and Side Effects

**State** is the collection of values a program holds at a given moment. **Mutation** is changing that state by reassigning a variable, adding to a list, or updating a field.

A **side effect** is any observable change a function makes beyond returning a value, such as mutating an argument or writing a file. A function without side effects whose output depends only on its inputs is **pure**.

| Concept | Meaning | Risk |
| --- | --- | --- |
| **Mutation** | Modifying existing data | Hard to track state |
| **Aliasing** | Two names, same object | Surprise modifications |

> **Pitfall:** `b = a` for a list does not copy. Mutating `b` also changes `a` because they share references.

## The Event-Driven World

An **event-driven** program inverts control: you register **handlers** or **callbacks** to run when events happen, and an **event loop** waits and calls them. The outside world decides the order.

Handlers communicate entirely through **shared state**. Because order is unpredictable, mutation bugs multiply.

| Threat | Consequence | Prevention |
| --- | --- | --- |
| **Blocking** | Freezes the event loop | Keep handlers short |
| **Re-entrancy** | State half-updated | Protect shared state |

> **Pitfall:** Assuming handlers run in causal order. No promise is made about which event fires first.

## Practice questions

5 of this lesson's 12 practice questions, with answers. The full set is in the app.

### 1. A function that writes to a global variable is as easy to test as one that only returns a value, provided both are correct.

**Answer:** False

**Why:** False. The pure function needs no fixture and no teardown, and its tests can run in any order. The one touching a global forces every test to set that state up and reset it, and makes tests order-dependent, which is why side effects get pushed to the edges and the middle of a program kept pure.

Page: https://tryals.app/practice/computer-science-i/state-mutation-and-side-effects/a-function-that-writes-to-a-global-variable-is-as-easy-to-test-as-one

### 2. Order these events so that every stated outcome is true at the moment it is written.

**Answer:**

1. Set data to the list [5]
2. Set alias to data, so both names now see [5]
3. Append 6 through alias, so data now reads [5, 6]
4. Set copy to an explicit copy of data, freezing it as [5, 6]
5. Append 7 to data, so alias now reads [5, 6, 7] while copy still reads [5, 6]

**Why:** Order decides everything here: the copy freezes the list as it was at that instant, so 6 must be appended before the copy and 7 after it. The alias, by contrast, has no such timing, it shares the one list forever, so the final append is visible through both data and alias but not through copy.

Page: https://tryals.app/practice/computer-science-i/state-mutation-and-side-effects/order-these-events-so-that-every-stated-outcome-is-true-at-the-moment

### 3. A function is called twice with identical arguments and returns a different answer the second time. Select every explanation the lesson's ideas allow.

A. The function keeps a counter of how many times it has been called
B. The function is pure
C. The function reads a global variable that changed between the calls
D. The function returns its argument unchanged
E. The function mutated one of its arguments during the first call

**Answer:** A. The function keeps a counter of how many times it has been called; C. The function reads a global variable that changed between the calls; E. The function mutated one of its arguments during the first call

**Why:** Any state that survives between calls can change the answer: a global read, an argument the first call mutated, or an internal counter. Purity rules this out by definition, so a differing answer is proof of impurity, which is exactly why pure functions are so much easier to test.

Page: https://tryals.app/practice/computer-science-i/state-mutation-and-side-effects/a-function-is-called-twice-with-identical-arguments-and-returns-a

### 4. A function sorts the list it is given rather than returning a sorted copy. Why is that worth documenting loudly?

A. Because the caller's data changes as a side effect
B. Because sorting in place is slower than returning a copy
C. Because in-place sorting is not thread-safe under any circumstances
D. Because it prevents the function from being tested

**Answer:** A. Because the caller's data changes as a side effect

**Why:** The caller's object is modified, so every other holder of that reference is affected and the surprise surfaces somewhere unrelated. Python encodes the distinction in its names — `sort()` mutates, `sorted()` returns — and the convention exists because the difference is invisible at the call site otherwise.

Page: https://tryals.app/practice/computer-science-i/state-mutation-and-side-effects/a-function-sorts-the-list-it-is-given-rather-than-returning-a-sorted

### 5. Sort each statement by whether it concerns the identity of an object or merely its value.

**Answer:**

- About identity (same object): Mutating through one name is visible through the other, There is only one list in memory, reached by two names, Rebinding one name leaves the other pointing at the old object
- About value (equal contents): Both lists currently hold 1, 2 and 3, The two lists compare as equal right now but are stored separately

**Why:** Identity is about how many objects exist; value is about what they contain at this moment. Two separate lists can be equal today and different after one append, whereas two names for one list can never disagree. Treating equality as if it implied identity is the aliasing trap the lesson names.

Page: https://tryals.app/practice/computer-science-i/state-mutation-and-side-effects/sort-each-statement-by-whether-it-concerns-the-identity-of-an-object
