Pass by Value vs Pass by Reference: The Gotcha That Breaks Brains
Change a variable inside a function — does the caller see it? Most popular languages pass the reference itself by value: a copy of the address, so you can mutate the shared object but can't reassign the caller's variable. The real split isn't value-vs-reference, it's mutate vs reassign.
Pass by value hands the function a copy — scribble on it, the caller's original is untouched. Pass by reference hands the function your actual variable — reassign it, and the caller sees the change. The gotcha in Java, Python, JS, and Ruby is that they pass the reference itself by value: a copy of the address. That lets you mutate the shared object through it (so a list's .append sticks), but reassigning your local copy of the address never moves the caller's variable (so lst = [9] is lost). The real question isn't value vs reference — it's whether the change mutates the shared object or reassigns the local variable.
Transcript
You change a variable inside a function. Does the code that called it see the change? Sometimes yes, sometimes no — and the rule confuses almost everyone. It comes down to one thing: what you actually hand the function — a copy, or the real thing? Let's settle it for good.
Pass by VALUE means the function gets a COPY of your data — like handing someone a photocopy of a document. They scribble all over it. Your original is untouched. Change the parameter inside the function, and the caller's variable doesn't budge. That's how primitives pass almost everywhere.
Pass by REFERENCE means the function gets your ACTUAL variable — not a copy, the real thing — like sharing the address of your house. Now they can change your variable itself — even reassign it to a whole new value — and you see every change. C-sharp's ref keyword works exactly like this.
Here's the twist that breaks brains. Java, Python, JavaScript, Ruby — they pass the reference itself BY VALUE. A copy of the address. So you CAN rearrange the furniture — mutate the object, and the caller sees it. But scribble a new address on your copy — reassign — and their variable never moves.
That's why 'Java is pass-by-value' is true even for objects. And why appending to a Python list inside a function sticks — but reassigning that list doesn't. The object is shared; the variable holding it is a copy. Mutation travels back; reassignment stays local. One rule explains all of it.
So stop asking 'value or reference?' In Java, Python, or JavaScript, you always get a copy — it just happens to hold an address. The question that predicts it: did you MUTATE the shared object, or REASSIGN your variable? So the one thing to remember — mutation travels back, reassignment stays home.