[Edu-sig] Pass by Reference

David MacQuigg macquigg at ece.arizona.edu
Fri May 16 22:48:26 CEST 2008


If there are no objections to my models and terminology, the next step is to describe exactly what happens when we pass an argument in C and in Python.

C is very helpful, since there is nothing hidden in this primitive language, and we can see exactly what is happening.  Also, there is no confusion about the definitions of "call-by-value" and "call-by-reference".  See Kernighan & Ritchie, 2nd ed. p.27.  Let's call these the "traditional" definitions.  In C there are only two ways to pass an argument - copy its value or copy a reference (pointer) to that value.

Again, the model and terminology for C in this discussion is:

   variable:(name, type, pointer) --> object:(value, address)

The variable name, type, and pointer are kept by the compiler.  The compiled module has just the actual data bits representing the value stored at a particular address.

Here is a simple program that calls a function with two parameters, one called by value, the other by reference.  
f(int a, int *b) { 
    a += 1;   // modifies a local variable 
   *b += 10;  // modifies the caller's variable 
}
main() { 
  int x = 0; 
  f(x, &x);   // pass the value and the pointer 
  printf("x = %d\n", x); 
}
// output is x = 10 
In the call to function f, the value of the caller's variable x is copied to the function's parameter a.  The function then operates on its own copy of this value, and the original data value is safe from any modification by the function.  This is "call-by-value" in C.

In that same call, the address of the caller's variable x is copied to the function's parameter b.  Operations on b then change the value of x, but not its type or address.  This is "call-by-reference" in C.

In Python, there is only one way to pass an argument.  There may be pointers flying around, but we never see them.  We will have to infer what is going on by doing some tests. Again, the model and terminology for our discussion is:

   variable:(name, pointer) --> object:(type, value, address)

Here is a simple program that calls a function with one parameter.

   >>> def f(b): b[:] = range(9)

   >>> x = ['abc', 'xyz']
   >>> f(x)
   >>> x
   [0, 1, 2, 3, 4, 5, 6, 7, 8]

In the call to function f, we must infer that a reference to the caller's variable x is copied to the function's variable b.  Operations on b then change the value of x, but not its type or address.

I know there are later complications ( What if x is immutable?  What if b gets re-assigned within the function? ), but right now I would like to focus on exactly what happens in the call to function f.

I'll pause once more to see if I've made any mistakes, before the third and final step - deciding what to call this thing that Python does in passing an argument.

-- Dave


At 12:41 PM 5/15/2008 -0700, David MacQuigg wrote:
>At 04:30 PM 5/14/2008 -0500, John Zelle wrote:
>
>>At some point, I have to just let this go, as I think we all on this
>>list have a pretty good understanding of the differences between C and
>>Python in terms of assignment and parameter passing. But let's _not_ use
>>the term "pass by reference" when talking about Python. You CANNOT
>>CHANGE THE CONTENTS OF THE VARIABLE THAT IS SUPPLIED AS AN ACTUAL
>>PARAMETER. It will still refer to the same object (contain the same
>>reference) regardless of what is done to the formal parameter. Hence,
>>the variable IS NOT passed by reference. The value of the variable
>>(which happens to be a reference) is copied. Pass by value is the
>>accepted label for this mechanism. Pass by reference means something
>>else (as I've pointed out in previous posts).
>>
>>Christopher's point on teaching the differences directly is, I think, a
>>good one. But we don't need to worry about that for beginners.
>
>I agree, the topic should not come up in a class for beginners, but the question I got was from a student in a class on C.  In that situation, it does help to explain Python's calling mechanism in terms that these students understand.  I've posted my answer at http://ece.arizona.edu/~edatools/ece175/Lecture/QnA.txt
>
>I used the phrase "like pass-by-reference" to avoid the controversy as much as I can.  As you can see from the references cited in my answer, the terms call-by-value and call-by-reference do not have universally accepted definitions, even among experts.
>
>The differences seem to come down to what we mean by the words "value" and "reference".  Everyone seems to have unstated assumptions about their meaning, probably depending on what language they are thinking about.  Perhaps it will help if we can agree on models for variables in C and Python.  Here are my models:
>
>In C, the type of an "object" (char, int, float, etc.) is associated with
>the variable name, not the object.
>
>   variable:(name, type, pointer) --> object:(value, address)
>
>In Python, type is associated with the object, not the variable name.
>
>   variable:(name, pointer) --> object:(type, value, address)
>
>As you can see, I've used the word "value" to mean the actual data associated with the object, and the word "pointer" to mean whatever it is that references the object (a real pointer in C, I assume a C-pointer in Python).
>
>I realize my diagrams may bias the discussion, so perhaps I should stop at this point and ask for alternative models or terminology.
>
>-- Dave




More information about the Edu-sig mailing list