🧩 Methods · Beginner

Pure functions & side effects in Java

Why methods that don't mutate state are easier to reason about.

🧩 The mysteryCall the same method twice with the same argument and get two different answers. Is that a bug, or a hidden secret inside the method?

Like a calculator button

A pure function's result depends only on its arguments, and it changes nothing outside itself. Same input, same output, every single time. Math.max(3, 7) is pure: it will be 7 today, tomorrow and forever.

static int add(int a, int b) { // pure
    return a + b;
}
static int square(int x) {     // pure
    return x * x;
}

Side effects

A side effect is anything a method does that's visible outside, besides returning a value: printing, changing fields, mutating its arguments, writing files or calling the network. Math.random() isn't pure either: it returns something different each call.

static int total = 0;
static void addToTotal(int x) {
    total += x; // changes a field!
}
🔮 Predict it

Same input, twice

What prints?

static int bonus = 0;
static int score(int base) {
    bonus += 5;
    return base + bonus;
}
void main() {
    System.out.println(score(10));
    System.out.println(score(10));
}
  1. 15 15
  2. 15 20
  3. 10 10
  4. 20 20
Show the answer

The method changes and reads shared state: bonus becomes 5, then 10. So the same argument gives 15 the first time and 20 the second. Not pure!

🤔 Think first

Is printing a side effect?

A method returns the right answer but also prints a log line. Is it pure?

Think about it, then reveal the answer

No. Printing changes something outside the method (the console), so it's a side effect, even if the return value is perfect. Side effects aren't bad; just keep them obvious and contained.

⚠️ The trap

The hidden side effect

A teammate's sortAndSum(data) returns the sum but also sorts the caller's array. Later code that relied on the original order breaks, far from the cause. The fix: sort a copy (data.clone()), or name and document the effect clearly.

static int sortAndSum(int[] data) {
    Arrays.sort(data); // sorts caller's!
    int sum = 0;
    for (int x : data) sum += x;
    return sum;
}

Keeping state out

✗ Hidden state
static int calls = 0;
static int addCalls(int x) {
    calls++;
    return x + calls;
}

Result depends on how often it was called before.

✓ Pure
static int add(int x, int y) {
    return x + y;
}

Everything it needs comes in as arguments; the result is all it gives back.

💼 In the real world

In real projects

Pure functions are a joy to unit-test: give input, check output, no fields, files or console to set up or inspect. (They can still throw on bad input.) They're also safe to call any number of times and from many threads at once, which is why modern Java style leans toward them.

Key takeaways

  1. Pure: output depends only on input, with no visible side effects
  2. Side effects: printing, changing fields, mutating arguments, I/O
  3. Pure methods are easy to test and safe to call any number of times
  4. Math.max is pure; Math.random is not

💡 A pure function is like a calculator: the same keys give the same answer, and pressing them doesn't rearrange your desk.

🤯 Did you know?

Java 8's java.time classes are immutable: date.plusDays(1) returns a new date instead of changing the old one. It was a deliberate fix for the old, mutable java.util.Date.

Practice questions

Which method is NOT pure?

  1. static int square(int x) { return x * x; }
  2. static int abs(int x) { return x < 0 ? -x : x; }
  3. static int next() { return ++counter; }
  4. static String twice(String s) { return s + s; }
Check your answer

static int next() { return ++counter; }. next() changes a field (counter) and returns a different value every call. The others depend only on their argument.

What does this print?

static int calls = 0;
static int addCalls(int x) {
    calls++;
    return x + calls;
}
void main() {
    System.out.println(addCalls(10));
    System.out.println(addCalls(10));
}
  1. 11 11
  2. 10 10
  3. 11 12
  4. Compile error
Check your answer

11 12. The method reads and changes a shared static variable, so the same argument gives 11 the first time and 12 the second.

World 6: Arrays! Storing 1,000 scores in 1,000 variables? Next you'll pack them into one array, and learn why a[3] can crash a program that holds three items.