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


_______________________________________________
Edu-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/edu-sig

Reply via email to