Finding the instance reference of an object

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


On Nov 5, 2008, at 12:29 AM, Dennis Lee Bieber wrote:

>> C++:
>> void foo(PersonPtr who) {
>> 	who->zipcode = 12345;
>> }
>>
> 	Please show us the type definition of "PersonPtr"

Sorry, that'd be obvious to anyone experienced in C++, but I shouldn't  
assume.  It would be:

typedef Person* PersonPtr;

It's a pretty standard idiom, precisely because it is so much more  
common to need a variable of the pointer type than of the class type  
itself.

>> Java:
>> void foo(Person who) {
>> 	who.zipcode = 12345;
>> }
>>
> 	Please show us the type definition of "Person"

No.  It's a class, and you can see that it defines a "zipcode" member;  
nothing more is needed for the sake of this example.  (The Java  
designers realized that needing object reference variables is so  
overwhelmingly more common than needing non-pointer variables, that  
they eliminated the pointer syntax and made every variable of object  
type actually a pointer to the object data, just as in RB, .NET, and  
Python.)

>> REALbasic/VB.Net:
>> Sub foo(ByVal who as Person)
>> 	who.zipcode = 12345
>> End Sub
>>
> 	Note they YOU, as the programmer, explicitly told the language to
> use a call-by-value

Correct; these languages support both call-by-value and call-by- 
reference.  "ByVal" is the default, but you can still specify it (as  
I've done here) if you want to be explicit.

> -- and you still have not shown us the definition of "Person"

Right, again, there is nothing you need to know about it not already  
evident from the example.

>> Python:
>> def foo(who):
>> 	who.zipcode = 12345
>>
> 	Note that there is NO PROGRAMMER CONTROL over the passing mechanism.

Quite right.  (Same too in Java.)  Some languages offer both call-by- 
value and call-by-reference; but Java and Python offer only call-by- 
value.

>> 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.
>>
> 	I do not... I see the programmer telling the language that a
> reference is to be taken of some object and that this reference is
> /then/ to be passed.

Quite right (and that's what I said).  The reference is being passed.   
By value.  And then that reference is used to mutate an object.

> AND the programmer is also (C++) explicitly dereferencing (by use of  
> ->)!

Yep, "->" is the dereference operator in C++; in Java, RB, .NET, and  
Python, it's ".".  Different characters, same meaning.

> The syntax, in C/C++ is different for
> accessing the parameter by value vs by reference (pointer -- C++ is
> smarter in that it allows declaring the parameter as a &ref and the
> language automatically takes the address on the caller's side, and
> dereferences on the called side -- but that notation is STILL a
> programmer responsibility).

Careful here -- a &ref parameter really is passed by reference; that's  
not the same as passing a pointer by value, which is what's shown  
above.  It's the C++ equivalent of the "ByRef" keyword in RB/VB.NET.

> Java passes /objects/ by reference, but passes "native" types (base  
> numerics) by value

No, it passes everything by value.  "who" in the Java example is not  
an object; it is an object reference.  It was passed by value.  If it  
were passed by reference, you'd be able to make a "swap" function that  
exchanges the objects referred to by two variables, but you can't.   
This is explained more fully here:

   <http://javadude.com/articles/passbyvalue.htm>

> -- can you create a Java example where you pass a base numeric by  
> reference?

No, because Java (like Python) has only call-by-value.

> 	By your argument, even FORTRAN is call-by-value.

No, FORTRAN's an oddball: it passes everything by reference.

> You obfuscate the mechanics used at the machine language level with  
> the semantics of the
> language itself.

No, I haven't said anything at all about what's happening at the  
machine language level, and I frankly don't care.  This is about how  
the language behaves.

> FORTRAN is the language commonly used to explain call-by-reference!

Quite right.  So, please try to convert any of those FORTRAN  
explanations into Python or Java.  Can't be done.  In C++ or RB/ 
VB.NET, it can be done only by using the special by-reference syntax  
(& or ByRef).

I'm not sure where you got the idea that I thought FORTRAN is call-by- 
value.  I never said or implied any such thing.  And the examples  
above aren't meant to prove that those languages are using by-value;  
they're meant to show that mutating an object via a reference passed  
in proves NOTHING about how that reference was passed.  This is to  
invalidate the argument (frequently heard around here) that Python  
must use call-by-reference since you can mutate an object passed to a  
function.

As should be painfully clear by now, that argument is total bunk.  You  
can pass an object reference by value, and use it to mutate the object  
it refers to just fine.  To test whether you're passing by reference  
or by value, you need to instead assign a new value to the formal  
parameter, and see whether that affects the actual parameter.

>
Cheers,
- Joe




More information about the Python-list mailing list