Quiz 2

Week 3: Side Effects of Procedures

2538 words
13 min read
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

# Week 3: Side Effects of Procedures > **BSCS1001 — IIT Madras BS Degree** **Prerequisite:** Topic 05 (Procedures & Parameters) **Cross-links:** BSCS1002-Python (Week 5 — Function Side Effects), BSCS2002-PDSA (Week 3 — Purity) ## 1. Motivation: What Happens to the Data?

Week 3: Side Effects of Procedures

BSCS1001 — IIT Madras BS Degree Prerequisite: Topic 05 (Procedures & Parameters) Cross-links: BSCS1002-Python (Week 5 — Function Side Effects), BSCS2002-PDSA (Week 3 — Purity)

1. Motivation: What Happens to the Data?

You write a procedure to compute the sum of Maths marks. You pass in a carefully sorted deck of cards (arranged by total marks, descending). After the procedure runs... the deck is in a different order. Did the procedure mess up your data? This question — "what state is the data in after a procedure runs?" — is the core of side effects.
Real-world analogy: You lend a friend a book. You expect it back in the same condition (no side effects). But if your friend is a bookbinder who repairs torn pages, you might want them to fix things (desirable side effect). The key is knowing what to expect.

2. What is a Side Effect?

A side effect occurs when a procedure modifies some data during its computation, beyond just returning a value. (Diagram)

Examples of Side Effects

Side EffectExample
Reordering cardsAfter iteration, cards are in Pile 2 (reverse order typically)
Modifying a listAdding/removing items from a list passed as parameter
Changing a dictionaryAdding/removing key-value pairs
Writing to a fileSaving results to disk
Printing outputDisplaying something on screen

The Key Question

Does the caller care if the data is modified?
Sometimes...The side effect...
✅ Doesn't matterAdding marks — card order irrelevant
✅ Is the GOALSorting the deck — the whole point
❌ Is a problemFinding max marks but losing card order

3. The Card Deck: A Concrete Example

Recall our standard iteration pattern:
sql
while (Pile 1 has more cards) {
    Pick a card X from Pile 1
    Move X to Pile 2
    // Process X
}

What Happens to the Deck?

Before ProcedureAfter Procedure
Pile 1: [1, 2, 3, 4, 5]Pile 1: []
Pile 2: []Pile 2: [5, 4, 3, 2, 1]
The deck has been reversed! Cards that were in order [1,2,3,4,5] are now in order [5,4,3,2,1].

Does the Reversal Matter?

Case 1: Summing marks → No! 1+2+3+4+5 = 5+4+3+2+1 = 15. Order doesn't affect addition. Case 2: Finding max → No! Max is the same regardless of order. Case 3: Checking for a pattern that depends on positionYes! If the original order encodes information (e.g., position in class), reversal destroys it.

4. Desirable Side Effects

Sometimes the side effect is the purpose of the procedure.

Example: Sorting the Deck

pseudo
Procedure SortDeck() {
    // Rearrange cards in descending order of Total marks
    // The side effect (rearranging) is the whole point!
}

Example: Deleting a Key from a Dictionary

pseudo
Procedure DeleteKey(d, k) {
    myd = {}
    foreach key in keys(d) {
        if (k ≠ key) {
            myd[key] = d[key]
        }
    }
    d = myd    // Side effect: d is modified
End DeleteKey

Example: Adding a New Student

pseudo
Procedure AddStudent(newMark) {
    marksList = marksList ++ [newMark]   // Side effect: list grows
    aValue = -1                          // Side effect: cache invalidated
End AddStudent

When Side Effects Are Desirable

SituationWhy It's OK
Sorting dataThe whole point is to rearrange
Updating a recordYou want the data to change
Accumulating in a passed listThe caller expects the list to grow
Caching/computing derived valuesSpeed up future operations

5. Undesirable Side Effects

Sometimes the side effect causes problems for the caller.

Example: Pronoun Resolution

In Week 6, we resolve pronouns to their matching nouns. The procedure requires the lists to be in sorted order (by serial number). If a procedure rearranges these lists as a side effect, the pronoun matching will fail.
pseudo
// This procedure has an UNDESIRABLE side effect:
Procedure FindOverlap(11, 12) {
    overlap = []
    foreach x in 11 {
        foreach y in 12 {
            if (x == y) {
                overlap = overlap ++ [x]
            }
        }
    }
    // Side effect: 12 has been consumed/restructured!
    return(overlap)
End FindOverlap

Why Undesirable Side Effects Are Dangerous

(Diagram) The caller assumed the data would be preserved. The procedure broke that assumption.

6. Interface vs Implementation

This is one of the most important concepts in the course.

The Interface

The interface is the contract — what the procedure promises to do.
AspectDescription
ParametersWhat inputs are needed
Return valueWhat is computed and returned
Side effectsWhat modifications (if any) are made
GuaranteesWhat assumptions the caller can rely on

The Implementation

The implementation is how the procedure achieves its contract — the actual code inside.

Why Separate Interface from Implementation?

(Diagram) Key principle: You can change the implementation as long as the interface stays the same. The caller shouldn't need to know — or care — about implementation details.

Example

sql
// Interface: Find maximum of a field
// Parameters: fld - the field to check
// Returns: the maximum value found
// Side effect: Cards are moved from Pile 1 to Pile 2
Procedure MaxMarks(fld) {
    // Implementation can be anything that satisfies the interface
    Max = 0
    while (Pile 1 has more cards) {
        Pick a card X from Pile 1
        Move X to Pile 2
        if (X.fld > Max) {
            Max = X.fld
        }
    }
    return(Max)
End MaxMarks
The interface tells the caller: "You'll get the maximum, but your cards will end up in Pile 2." If the caller needs to preserve card order, they should make a copy first.

7. The Procedure Contract

Every procedure comes with a contract that specifies: (Diagram)

Contract Examples

Contract A: SumMarks — No side effects matter
pseudo
Functionality:
  - Parameters: gen (gender), fld (field name)
  - Returns: Sum of fld for students of gender gen
Data Integrity:
  - Side effect: Cards are moved to Pile 2 (doesn't affect computation)
  - Predictable: Yes — deck will be reversed
Contract B: DeleteKey — Side effect is essential
sql
Functionality:
  - Parameters: d (dictionary), k (key to delete)
  - Returns: nothing (void)
Data Integrity:
  - Side effect: Key k is removed from dictionary d
  - Predictable: Yes — exactly one key removed
Contract C: PronounMatcher — Side effects NOT tolerated
pseudo
Functionality:
  - Parameters: nounList, pronounList (both sorted)
  - Returns: Matched pairs
Data Integrity:
  - Side effect: NONE — input lists must remain sorted
  - Guarantee: Input lists are NOT modified

8. Side Effects with Collections

Lists and Side Effects

When a procedure receives a list, modifying it is a side effect:
pseudo
Procedure AddItem(myList, item) {
    myList = myList ++ [item]    // Side effect: modifies the list
End AddItem

Avoiding Side Effects with Lists

To avoid side effects, work on a copy:
pseudo
Procedure AddItemSafe(myList, item) {
    newList = myList              // Make a copy
    newList = newList ++ [item]   // Modify the copy
    return(newList)               // Return the modified copy
End AddItemSafe

The Side-Effect-Free Pattern

sql
// WITH side effect (procedure modifies input)
Procedure DeleteKey(d, k) {
    foreach key in keys(d) {
        if (k == key) {
            remove key from d     // d is changed!
        }
    }
}
// WITHOUT side effect (procedure returns new dictionary)
Procedure DeleteKey2(d, k) {
    myd = {}
    foreach key in keys(d) {
        if (k ≠ key) {
            myd[key] = d[key]    // Building new dictionary
        }
    }
    return(myd)                  // Original d is unchanged
End DeleteKey2
// Caller must reassign:
myd = DeleteKey2(myd, k)         // Caller explicitly updates reference

9. Managing Side Effects

Best Practices

PracticeDescriptionExample
Document side effectsState them in the contract"Note: modifies the input list"
Make copiesWork on copies when caller needs originalnewList = oldList
Use pure functionsNo side effects at allReturn new data instead of modifying
Minimize scopeOnly modify what you mustDon't touch unrelated data
Be predictableSame inputs → same side effectsDon't surprise the caller

Decision Flowchart

(Diagram)

10. Comparison Table

Pure vs Impure Procedures

AspectPure ProcedureImpure Procedure
Side effectsNoneHas side effects
Deterministic?Yes (same inputs → same output)May vary based on state
TestingEasy (no state to manage)Harder (need to set up state)
PredictabilityVery predictableLess predictable
ExampleMaxMarks(fld)AddStudent(newMark)
Caller concernJust the return valueReturn value + state changes

Desirable vs Undesirable Side Effects

AspectDesirableUndesirable
Is it expected?Yes, caller knowsNo, caller is surprised
Is it documented?Yes, in contractNo, or poorly documented
Does it help?Yes, it achieves the goalNo, it creates problems
ExampleSorting a listReversing a sorted list
How to handleDocument and embraceRefactor to avoid

11. Practice Questions

Basic Questions

Q1. What is a side effect in a procedure?
Show Answer
A side effect occurs when a procedure modifies some data during its computation, beyond just returning a value. Examples: reordering cards, modifying a list, changing a dictionary. Q2. Give one example of a desirable side effect and one example of an undesirable side effect. Show Answer
  • Desirable: Sorting a deck of cards (the rearrangement IS the goal)
  • Undesirable: A procedure that finds max marks but accidentally reverses the deck, destroying the original order that another procedure relied on. Q3. What is the difference between a procedure's interface and its implementation? Show Answer
  • Interface — the contract: what parameters, what return value, what side effects
  • Implementation — the actual code inside the procedure
You can change the implementation without affecting the caller, as long as the interface stays the same. Q4. In the standard iteration pattern, what side effect occurs to the card deck? Show Answer
Cards are moved from Pile 1 to Pile 2. Since cards are picked from the top of Pile 1 and placed on top of Pile 2, the deck ends up in reverse order compared to the original.

Intermediate Questions

Q5. Explain why the following code has a side effect and whether it's desirable:
pseudo
Procedure DoubleList(L) {
    i = 0
    while (i < length(L)) {
        L[i] = L[i] * 2
        i = i + 1
    }
End DoubleList
Show Answer
Side effect: The input list L is modified — each element is doubled.
Is it desirable? That depends on the contract. If the procedure is called "DoubleList" and the caller expects L to be modified, then YES. But if the caller expects a new list to be returned (and L untouched), they would be surprised.
Better design: Either:
  1. Document: "Side effect: modifies L in place"
  2. Or make it pure: create and return a new list Q6. Rewrite DeleteKey so it has NO side effects (pure function). Show Answer
pseudo
Procedure DeleteKeyPure(d, k) {
    newDict = {}
    foreach key in keys(d) {
        if (key ≠ k) {
            newDict[key] = d[key]
        }
    }
    return(newDict)
End DeleteKeyPure

// Usage: myDict = DeleteKeyPure(myDict, "someKey")
// Original myDict is unchanged; we reassign the result
Q7. If a procedure has an undesirable side effect, what are two ways to fix it?
Show Answer
  1. Work on a copy: Inside the procedure, copy the input data and work on the copy. Return the modified copy instead of changing the original.
  2. Document it: If the side effect cannot be avoided, clearly document it in the procedure's contract so the caller knows what to expect.
Q8. Consider: procedure A sorts the deck, then calls procedure B to find the average. After both run, what state is the deck in?
Show Answer
The deck is in whatever state procedure A left it (sorted, if B doesn't rearrange). But the standard iteration pattern in B moves cards from Pile 1 to Pile 2, which reverses them. If A sorted descending, after B the cards are in ascending order (since Pile 2 is reversed from Pile 1).
This is a classic example of unexpected interaction between side effects.

Advanced Questions

Q9. Design a procedure contract for a function FindCommonElements that takes two sorted lists and returns their intersection. Specify parameters, return value, AND side effects.
Show Answer
pseudo
// Contract for FindCommonElements
// Parameters:
//   list1 - sorted (ascending) list of integers
//   list2 - sorted (ascending) list of integers
// Returns:
//   A new list containing elements present in both list1 and list2
// Side effects:
//   NONE - input lists are NOT modified
//   (Internal implementation uses first() and rest() which modifies
//    the list copy, not the original)

Procedure FindCommonElements(list1, list2) {
    common = []
    // Implementation that avoids side effects...
    return(common)
End FindCommonElements
Q10. Trace the side effects in this sequence:
pseudo
1. Create list L = [3, 1, 4, 1, 5]
2. Call Sort(L)          // Sorts L ascending
3. Call Reverse(L)       // Reverses L
4. Call Max(L)           // Finds max
What is L after each step? Which side effects are desirable?
Show Answer
StepL after stepSide effect desirable?
Start[3, 1, 4, 1, 5]
After Sort(L)[1, 1, 3, 4, 5]✅ Yes (sorting is the goal)
After Reverse(L)[5, 4, 3, 1, 1]✅ Yes (reversing is the goal)
After Max(L)[5, 4, 3, 1, 1] (unchanged)✅ No side effect (pure function)
Final L = [5, 4, 3, 1, 1] (reversed from original) Q11. Why is it important to document side effects in a procedure's contract? Show Answer
  1. Caller awareness — The caller needs to know if their data will be modified
  2. Correctness — The caller can account for side effects in subsequent code
  3. Debugging — If something goes wrong, documented side effects help trace the issue
  4. Maintainability — Future changes to the procedure must preserve the contract
  5. Reusability — Other programmers can use the procedure correctly
Without documentation, callers might assume their data is safe when it isn't. Q12. In the classroom dataset example (Week 10), addStudent resets aValue to -1 as a side effect. Explain why this side effect is both desirable and potentially dangerous in a concurrent context. Show Answer
Desirable because: When a new student is added, the cached average (aValue) becomes stale. Resetting it to -1 forces average() to recompute the correct value. This is a necessary side effect for correctness.
Dangerous because (concurrent context): If average() is running at the same time as addStudent(), there's a race condition. The average might read aValue while addStudent is changing it, getting an incorrect result. Or average might compute using the marksList while addStudent is appending to it — leading to corrupted data.
This is why concurrent access needs atomicity (non-concurrent access to shared state).

📚 Cross-References

CourseTopicConnection
BSCS1002 (Python)Week 5 — FunctionsMutable vs immutable arguments
BSCS2002 (PDSA)Week 3 — ModularityPure functions vs procedures
BSCS2002 (PDSA)Week 8 — GraphsSide effects in graph algorithms

Quiz Tip: Side effect questions ask you to predict what state data is in after a procedure. Always trace the deck/card movements! Join Discord PreviousProcedures & ParametersNextNested Iterations
Document outline

Keep your place and jump directly to a heading.

Table of Contents
System Normal // Awaiting Context

Intelligence Hub

Navigate the knowledge graph to generate context. The Hub adapts dynamically to surface backlinks, related notes, and metadata insights.