Finding the instance reference of an object

Joe Strout joe at strout.net
Thu Nov 6 11:59:37 EST 2008


On Nov 4, 2008, at 12:57 PM, Hendrik van Rooyen wrote:

>> 4. You now see how a mutating an object within a function tells you
>> NOTHING about how the reference to that object was passed.
>
>> 5. You see that the first three languages above are passing a
>> reference by value and using that to mutate and object, yet for
>> reasons still mysterious, the Python example (which has exactly the
>> same behavior) must be doing something different.
>
> This is dialectic nit picking - WTF makes "passing a reference by  
> value"
> different from "passing a reference" - the salient point is that its  
> a reference
> that is passed

I know it seems nit-picky on the surface, but it is important.  It is  
the distinction that lets you answer whether:

def foo(x):
    x = Foo()

x = Bar()
foo(x)

...results in x (after the call) now referring to a Foo, or still  
referring to a Bar.

If x is a reference passed by value, then the assignment within the  
foo method can't affect the x that was passed in.  But if it is passed  
by reference, then it does.  (Also, if it is passed by reference, then  
you probably wouldn't be able to pass in a literal or computed value,  
but only a simple variable.)

> - would you expect another level of indirection - a reference to
> the reference, or what, before you admit that the thing that is  
> passed is a
> reference and not a copied value of the OBJECT that is of interest.

Um, no, I've admitted that it's a reference all along.  Indeed, that's  
pretty much the whole point: that variables in Python don't contain  
objects, but merely contain references to objects that are actually  
stored somewhere else (i.e. on the heap).  This is explicitly stated  
in the Python docs [1], yet many here seem to want to deny it.

> Looks to me that even if there were ten levels of indirection you  
> would still
> insist that its a "pass by value" because in the end, its the actual  
> memory
> address of the first pointer in the queue that is passed.

No, it's entirely possible for an OOP language to have pass by  
reference, and, to put it your way, this adds one more level of  
indirection.  Look at the C++ and RB/VB.NET examples at [2].  But  
Python and Java do not offer this option.

> If that is what you mean, it is obviously trivially true - but then  
> ALL
> calling can only be described as "call by value" - which makes  
> nonsense
> of what the CS people have been doing all these years.

That would indeed be nonsense.  But it's also not what I'm saying.   
See [2] again for a detailed discussion and examples.  Call-by-value  
and call-by-reference are quite distinct.

> "Calling by value" is not a useful definition of Pythons behaviour.

It really is, though.  You have to know how the formal parameter  
relates to the actual parameter.  Is it a copy of it, or an alias of  
it?  Without knowing that, you don't know what assignments to the  
formal parameter will do, or even what sort of arguments are valid.   
Answer: it's a copy of it.  Assignments don't affect the actual  
parameter at all.  This is exactly what "call by value" means.

Best,
- Joe

[1] http://www.python.org/doc/2.5.2/ext/refcounts.html
[2] http://www.strout.net/info/coding/valref/




More information about the Python-list mailing list