Latticework

Command Palette

Search for a command to run...

Functional Programming Fundamentals

Pure Functions

16 min

Explanation

A pure function always produces the same output for the same input, and doesn't change anything outside itself — no mutating an argument, no printing, no reading a global variable, no network/file access. Compare:

# impure -- mutates the argument, returns None
def add_impure(lst, item):
    lst.append(item)

# pure -- returns a new list, leaves the original untouched
def add_pure(lst, item):
    return lst + [item]

Both "add an item" — but add_pure is far easier to reason about: call it as many times as you want, in any order, from anywhere, and it will never surprise you by having changed something you didn't expect.

Try it

original is provably untouched -- that's the whole guarantee purity gives you. An impure version using .append() would have silently changed 'original' too, which is often not what you want.

Loading editor…
Explanation

Purity matters most once code gets complex: a pure function is trivially testable (same input always gives the same output, no setup needed), and safe to run in parallel (no shared mutable state means no race conditions) or cache (same inputs always give the same answer, so the result can be reused). Most real programs mix pure and impure code — the functional-programming discipline is pushing as much logic as possible into pure functions, and keeping the unavoidable impure parts (reading a file, printing output, mutating a database) as a thin layer around them.

Exercise

Write `add_pure(lst, item)`: return a NEW list with `item` appended, WITHOUT mutating `lst` (unlike `lst.append(item)`, which mutates in place and returns None).

Exercise

Write `total_pure(prices, tax_rate)`: return the total of `prices` with tax applied (`sum(prices) * (1 + tax_rate)`), rounded to 2 decimals. No mutation, no printing, no reading external state — just input in, output out.

Quiz

What makes a function 'pure'?

Checkpoint

You can write pure functions that avoid mutating their inputs, and understand why purity makes code easier to test, reason about, and run safely.