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