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

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to