Programming Fundamentals › Collections
Pass by Value vs Reference
Whether a function receives a copy or a reference to the caller's data.
Also known as: call by value, call by reference, pass by reference, call by sharing
When you pass a variable into a function, does the function get its own copy, or access to the caller’s original?
- Pass by value: the function gets a copy. Changing it has no effect outside.
- Pass by reference: the function gets an alias to the caller’s variable. Changing it changes the caller’s data.
Languages differ. C++ has both. Go passes copies. Python, JavaScript and Java do something in between that’s often called call by sharing: the function receives a copy of the reference, so both names point at the same object.
What call by sharing means in practice
def add_item(items):
items.append("x") # changes the caller's list
def replace(items):
items = ["y"] # rebinds the local name only
my = ["a"]
add_item(my) # my == ["a", "x"]
replace(my) # my is still ["a", "x"]
Two rules cover it:
- Mutating the object through the parameter is visible to the caller.
- Reassigning the parameter is not.
Immutable values (numbers, strings, tuples) can’t be mutated, so they behave as if they were passed by value.
The bug to avoid
A function that quietly edits its input:
def top_three(scores):
scores.sort(reverse=True) # reorders the caller's list!
return scores[:3]
def top_three_safe(scores):
return sorted(scores, reverse=True)[:3] # new list; input untouched
Prefer returning a new value over modifying arguments. If you must keep a private copy, make one explicitly, and remember a plain copy is shallow: nested objects are still shared.
Rule of thumb: check your language’s rule once, then assume a function can change any mutable argument unless it says otherwise.