Pure functions and side effects
Functional style favours pure functions: same input always yields the same output with no hidden state changes. Avoid mutating arguments or globals. Pure functions are easier to test, reason about, and parallelise.
Closures and currying
A closure captures variables from its enclosing scope:
def multiplier(n):
return lambda x: x * n
double = multiplier(2)
print(double(5)) # 10
This enables currying, fixing some arguments to create a new function.