13
$\begingroup$

In general, there are two ways arguments can be passed to a function. Functions can either be passed a reference to an object, or the value of that object. This is something that my students often struggle to understand, and I struggle to explain.

What are some good analogies for pass by reference and pass by value? What are some pseudo-code (or real code) examples I could show that would function differently in a pass by reference language and a pass by value language?

This is already covered on Stack Overflow, but I'd like to get some answers more specifically about how to teach it and less about what the designation is.

$\endgroup$
5
  • 6
    $\begingroup$ This is not an answer, so I'll leave it here in the comments. I think you'll like this figure $\endgroup$
    – James
    Jun 12, 2017 at 11:23
  • $\begingroup$ What part are they struggling about? Have you already established how references work (without function calls)? $\endgroup$
    – Bergi
    Jun 16, 2017 at 17:11
  • $\begingroup$ In practice there are two ways that arguments are passed in the majority of programming languages, but in general, there are quite a few different ways: en.wikipedia.org/wiki/Evaluation_strategy $\endgroup$ Jul 24, 2017 at 21:56
  • $\begingroup$ Re, "...a reference to an object." I would not say "object," I would say "variable." There's been some heated arguments on StackOverflow over whether function arguments are passed by value or by reference in the Java programming language. The correct answer is, Java function args are always passed by value, but the controversy keeps returning because most Java "values" are references to objects. IMO, the key is, calling foo(x) can not assign the variable x if x is passed by value. It maybe can mutate the object to which x refers, but it can not change which object x refers to. $\endgroup$ Mar 9, 2020 at 13:58
  • $\begingroup$ Do you really have pass by reference? Ok it exists in C++ (and Pascal!). For most other languages... one should read this by Steven d'Aprano. $\endgroup$
    – Rusi
    Nov 9, 2020 at 12:10

12 Answers 12

7
$\begingroup$

The canonical example (at least in C) involves swapping two values:

#include <stdio.h>

void swapByValue(int a, int b)
{
    int temp = a;
    a = b;
    b = temp;
}

void swapByReference(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main(void)
{
    int a = 13;
    int b = 42;

    printf("a is %d\n", a);
    printf("b is %d\n\n", b);

    printf("Swapping...\n");
    swapByValue(a, b);
    printf("a is now %d\n", a);
    printf("b is now %d\n", b);
    printf("Not swapped!\n\n");

    printf("Swapping...\n");
    swapByReference(&a, &b);
    printf("a is now %d\n", a);
    printf("b is now %d\n", b);
    printf("Swapped!\n");
}

In terms of analogies and to further your own, you could talk specifically about sharing privileges on Google Drive (assuming that is something your students are familiar with). When I pass by value, I in effect give someone the right to copy the original (i.e. "Can view" rights) and make whatever changes they would like. Those changes have no bearing on my original copy, and the other person would now have to explicitly return the favor and give me "Can view" rights to see the work. With passing by reference, I am giving direct access to the original (i.e. "Can edit" rights). You can now modify the original without needing to return anything.

The idea of sharing right should be universal enough beyond just Google: the privileges of read-only v. editing should resonate enough. However, I would caution that this might be another area where analogies may not clarify things as much as one might hope.

With the C example, it's clear - even before explaining the syntax - that one function swaps values successfully and one does not. Students can now work backwards and problem solve to identify why they think one works and one doesn't. As a result showing a working example where one function passes by value and one does not may be a better teaching tool. This would enable a more Socratic approach where you as the instructor can pose questions about why they think one does something different from the other and in turn they may come to understand the syntax for themselves before you formally teach them anything. If you compare the two functions, the only difference is the use of * throughout swapByReference and the fact that it is called with an ampersand in front of each argument. That creates a teachable moment in terms of syntax.

$\endgroup$
9
$\begingroup$

Since I was tired of the easy IT examples which all revolved around sharing files and documents, I started using the following analogies to explain pass by value and by reference.

My cat ("Mr Doorknob") sometimes wanders off to my neighbour. They call him "Cirmi", but of course he is still the same cat. If they feed him, he comes home fat and satisfied, if their dog licks him, he comes home covered in saliva.
This is a bit like passing a variable by reference: they might give him a different name, but it is the same cat. Whatever is done to the passed cat in the neighbour's garden will be visible on the cat when he finally comes home. (I actually like this because it helps them understand the "different name thing".)

As for passing by value, my neighbours really liked my new sunshade. They asked me where I got it from, and they bought one themselves. It looked identical in the beginning, but theirs got pooped on by a bird. This, obviously, didn't affect mine, it is still as shiny and clean as it was.


Many things can be used as analogy for pass by reference: renting books from a library, and seeing the marks in it someone else made; lending some item to a friend, etc.
I find it harder to come up with real life examples for passing by value, but one example is photo copying course notes, or artists (or forgers) copying famous paintings.

So, lending someone my course notes VS letting them make a copy of my course notes, then see them pour coffee over the notes while they are learning from it - in case one, my originals are ruined, in case two, my originals are safe. (Instead of pouring coffee, we can have them add improvements/comments to the notes, to make it positive instead of negative).

$\endgroup$
3
  • $\begingroup$ Where this breaks down, I think, is in the tricky case. (Apologies for the lack of formatting, but comments don't seem to permit them) public void silly(int[] g){ g[0] = 7; g = new int[10]; g[1] = 7; } $\endgroup$
    – Ben I.
    Jun 13, 2017 at 10:35
  • $\begingroup$ @BenI. Oh you are right, this is by no means a perfect analogy. I use this to explain the basic concept of passing variables between subroutines and functions, and to help with one specific question I got a lot of times: "how come it is called abc in one routine and xyz in the other if it is the same thing?" $\endgroup$
    – vacip
    Jun 13, 2017 at 11:15
  • $\begingroup$ C is a purely pass-by-value language. You must ask: what is the variable storing? Passing pointers passes a copy of the memory address specified by the pointer. There is no genuine pass by reference in C. $\endgroup$ Dec 7, 2020 at 1:16
4
$\begingroup$

A good analogy for this is passing a document of some sort to a friend. Here is how the analogy goes: I have a document. I want to give you (my friend) the document so you can make some changes and I can get those changes from you. How would I do this? There are two possible ways:

In a pass by reference language, there would only be one document that I have. I would share that document with you so that we both can access it and change it. You could make your changes, and I would already have the same document, so I'd already have all your changes because we've been working on the exact same document. In psudo-code:

my_document = "Hello World!";

function make_your_changes(document) {
  document = document + " With Changes!";
  return document;
}

make_your_changes(my_document);
my_document == "Hello World! With Changes!";

In a pass by value language, I'd have to duplicate the document and give you a copy. You'd then make your changes and give your copy to me. I'd then have to use your document rather than mine, because your copy would have the changes. In this case, there would two copies of the document. They would have been then same when I gave a copy of my document to you. You'd have to give a different document back to me with your changes. Importantly, we end up with two different documents. In pusdo-code:

my_document = "Hello World!";

function make_your_changes(document) {
  document = document + " With Changes!";
  return document;
}

your_document = make_your_changes(my_document);
my_document == "Hello World!";
your_document == "Hello World! With Changes!";
$\endgroup$
0
4
$\begingroup$

I start by talking about Addresses. (pointers) (shh!)

Yes, we took a long detour trying to avoid the pointer concept, but it has failed, because, well, addressing is part of how computers work. So, when I talk about Classes and Objects, the very first thing that comes up is the difference between the instance, and the variable that I use to reference it. I explain this by saying:

The Object is like my house, it exists somewhere.
The Reference to it is like writing the address down on paper.

If I throw the paper away, the house is still there, but I might not know how to get there anymore. I can make copies of the address / paper, but there is still only one house.

Then I say that pass-by-reference is giving you the address so that you can go there and do things to it. Passing by value is like giving you your own copy, and what you do does not affect the original. This seems to be well-received.

$\endgroup$
1
  • $\begingroup$ Very nice analogy with the house address. I already use houses and architectural plans as an analogy for instances and classes, so this fits nicely into my current practice. :) $\endgroup$
    – Ben I.
    Jun 15, 2017 at 15:04
1
$\begingroup$

I like the analogy of sending a file by email.

When emailing a file you have two options:

1) You can send an email with an attachment that someone can download and edit. Any changes they make wont affect you or anyone else unless they send it back.

2) Alternatively you can send a link to a file on Google Docs or some other cloud hosting provider. Any changes that the recipient makes will affect the sender and anyone else who looks at the file.

Passing a parameter by reference is like emailing a link to a cloud-hosted file. You should do this if you're sending large amounts of data to avoid duplication.

Passing a parameter by value is like sending an email with an attachment. You should do this if a particular person / part of the program needs their own copy of the data / file in a way that doesn't interfere with anyone else / other parts of the code.

Both have their uses if you're aware of the implications.

$\endgroup$
1
$\begingroup$

The best tutorial on pass-by-value vs pass-by-reference I've seen is Cup Size -- a story about variables and its follow up Pass-by-Value Please.

These talk about variables as cups that can hold different items, and references as remote controls that you can put in a cup. You can have two remote controls in two cups that control the same TV, and replacing one of the remote controls with another one that controls a different TV doesn't affect the first TV at all.

$\endgroup$
1
$\begingroup$

Pass by reference. You change the original and everyone sees. For example drawing on the Mona Lisa ruins it for everybody.

Pass by value. You take a photo of the Mona Lisa and you can do what you want with it as the original is still in the state you found it in.

enter image description here

$\endgroup$
1
$\begingroup$

To add to Simon's answer, I've used the "phone number" analogy, but using a phone number as a reference to a person, rather than as a reference to a phone. The example is meant to explain the behaviour of algorithms like the below, when you have a list created like [Person()] * 10 in Python:

for person in people:
    person.wear_hat()

If you really had a list of 10 people, then the result would be that each person in the list is wearing a hat. But the real behaviour is like you have a list of ten phone numbers. You call the first number and tell them to put on a hat, then you call the second number and tell them to put on another hat, and so on. But the list has ten copies of the same phone number, so you just called the same person ten times, and by the end of the loop the person on the other end of the phone is wearing ten hats.

If you want to be completely accurate, this isn't exactly the distinction between "passing by reference" and "passing by value". In fact, every value in Python is a reference, and references are always passed by value. (See also this explanation of the same fact about non-primitive types in Java.) That said, the example elucidates how using references can have different behaviour to using copies, which is the key point you're trying to get across; conceptually the same example could be written in C++ using reference parameters.

I also think the phone number/person analogy for references is good because it evokes the idea that calling a method is a form of message passing, an important concept in OOP and concurrent programming.

$\endgroup$
1
$\begingroup$

I found a nice and visual metaphor for this. It won't work for aphantasiacs (probably) as it requires imagination of surreal objects.

First is to make clear distinction between values and addresses. But I won't call those "values" and "addresses". I'll call those boxes and ... tentacles!

Yes! Tentancles! So imagine a number as a box, and imagine this box extrude or generate tentacles. Many tentacles, or no tentacles. Some tentacles are named, other anonymous. But all these tentacles belong to (originate from) same box.

So, a function is just a transformer box -- you put stuff in, and get some result out. But due to technical limitation of this transformer box, all the stuff we put in -- we put just a copy of that stuff. Yeah, each time we run a function machine, we make copies of boxes and use those there. But this also allows us to preserve original boxes, so that's good news.

But functions are fine with putting tentacles as inputs. Yes, we have to duplicate that tentacle, but it still originates from some box. And when function acts on tentacle, it first "pulls" the box and does some work. It can potentially modify that box. It was tentacle what was made a copy, not a box itself.

So pass-by-value is when function expects a copy of box, and pass-by-ref is when function expects a copy of box tentacle.

(this metaphor is quite generalizable. Tentacle has a small box on it's end. And that small box can also generate tentacles! int** essentially)


Most other answers are good, but I found that abstract "address" or "index" are hard to imagine, so they are ignored and this starts doomed spiral of failure to understand. Thinking of "address" or "index" already requires rule-based thinking, which we can't assume in general audience.

$\endgroup$
0
$\begingroup$

I have N sheets of paper taped to the wall, labeled #1, #2, #3, etc. to N. Each sheet of paper has different words or animal pictures (etc.) on it, but is turned over so you can't see it.

To let you read what's on one of these sheets of paper, I can do two things:

  1. I can copy the contents ("value") of what's on one of the sheets of paper, and hand the copy to you, and let you read and write on your copy. If you do write on your copy, note that the sheet on the wall remains unchanged by you.

  2. I can tell you the number of the selected sheet on the wall, and let you go to the wall, turn the sheet over so you can see the contents, and read and write on that sheet of paper. The number of the selected sheet of paper is its "reference". I get to see your changes (whether I want them or not!). Note that if there is a ton of stuff on the sheet of paper, the reference is a lot shorter and easier to give you than redrawing all the stuff onto a copy.

$\endgroup$
2
  • $\begingroup$ As I said to Simon M, Your answer suggests that pass by value is more work for the computer than pass by reference, but that may be misleading. I know that in PHP pass by value is implemented using Copy On Write, so the data is not physically copied if it doesn't need to be. $\endgroup$
    – bdsl
    Sep 3, 2017 at 19:24
  • $\begingroup$ Note that copy-in-write is an implementation optimization, perhaps an optional one in the language definition. $\endgroup$
    – hotpaw2
    Sep 3, 2017 at 19:43
0
$\begingroup$

Pass by reference: "Can I have your phone number?"

Pass by value: "Can I have your phone?"

The point is that 'things' have both a physical form, but also a meta form. Humans have a body, and a name. The physical form is the thing itself, in all its nuance and complexity, and is heavyweight and non-trivial to duplicate. The meta form is a mere reference to physical, and therefore lightweight and easy to reproduce. I have only one phone, and creating a duplicate of it would be a non-trivial thing to do, but I can give my phone number out to millions of people with little cost.

$\endgroup$
5
  • 1
    $\begingroup$ Welcome to Computer Science Educators! We're glad you could join us. Would you mind elaborating on this analogy to explain why it works? It may seem obvious to you or me, but the explanation could be useful for someone else. $\endgroup$
    – thesecretmaster
    Jun 16, 2017 at 14:25
  • $\begingroup$ The point is that 'things' have both a physical form, but also a meta form. Humans have a body, and a name. The physical form is the thing itself, in all its nuance and complexity, and is heavyweight and non-trivial to duplicate. The meta form is a mere reference to physical, and therefore lightweight and easy to reproduce. I have only one phone, and creating a duplicate of it would be a non-trivial thing to do, but I can give my phone number out to millions of people with little cost. $\endgroup$
    – Simon M
    Jun 16, 2017 at 16:06
  • 1
    $\begingroup$ You could, if you want, edit this explanation into your answer (by using the "edit" link on the bottom left side) so a new visitor doesn't have to read through the comments but can get everything by reading the answer - this is often considered good practice on Stack Exchange sites. $\endgroup$
    – TuringTux
    Jun 16, 2017 at 17:13
  • $\begingroup$ Your answer suggests that pass by value is more work for the computer than pass by reference, but that may be misleading. I know that in PHP pass by value is implemented using Copy On Write, so the data is not physically copied if it doesn't need to be. $\endgroup$
    – bdsl
    Sep 3, 2017 at 19:23
  • $\begingroup$ There's almost nothing in common between the list of things you can do with a phone number, and the things you can do with a phone. $\endgroup$ Mar 9, 2020 at 14:01
0
$\begingroup$

The way I keep the 2 straight is this:

I can quote a source in 2 ways. I can either refer to it, while still adding my own ideas and tailoring the information to fit my needs, or just take the information at face value and show it to you while keeping my thoughts to myself.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.