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/
--
http://mail.python.org/mailman/listinfo/python-list