On Nov 6, 2008, at 12:44 PM, Arnaud Delobelle wrote:
I know this thread has grown quite personal for some of its
participants. I am posting in a spirit of peace and understanding :)
Thanks, I'll do the same.
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.
You refer to docs about the *implementation* of Python in C. This is
irrelevant.
It's supportive. I don't understand how/why anybody would deny that
Python names are references -- it's all over the place, from any
discussion of "reference counting" (necessary to understand the life
cycle of Python object) to understanding the basics of what "a = b"
does. It seems absurd to argue that Python does NOT use references.
So the official documentation calmly discussing Python references,
with no caveats about it being internal implementation detail, seemed
relevant.
Also, you talk about variables 'containing' something. In Python,
variables don't contain anything, they're simply names for objects.
You say "names for", I say "references to". We're saying the same
thing (though I'm saying it with terminology that is more standard, at
least in the wider OOP world).
'Pass by value' is not relevant to Python as variables do not contain
anything. 'Pass by reference' is not relevant to Python as the
language
doesn't have the concept of object reference (in the sense of e.g. C++
reference).
Both are relevant to answering simple questions, like what happens to
x in this case:
def foo(spam):
spam = 5
foo(x)
This is a basic and fundamental thing that a programmer of a language
should know. If it's call-by-reference, then x becomes 5. If it's
call-by-value, it does not.
Why the resistance to these simple and basic terms that apply to any
OOP language?
Here lies, IMHO, the reason why you think you need Python to 'pass by
value'. As you believe that variables must contain something, you
think
that assignment is about copying the content of a variable.
Assignment
in Python is simply giving a new name to an object.
What does "give a new name to an object" mean? I submit that it means
exactly the same thing as "assigns the name to refer to the object".
There certainly is no difference in behavior that anyone has been able
to point out between what assignment does in Python, and what
assignment does in RB, VB.NET, Java, or C++ (in the context of object
pointers, of course). If the behavior is the same, why should we make
up our own unique and different terminology for it?
To understand variables (which I prefer to call 'names') and function
calls in Python you need simply to understand that:
- a variable is a name for an object
A reference to an object, got it.
- assignment is naming an object
Assigning the reference to the object, yes.
- the parameters of a function are local names for the call arguments
Agreed; they're not aliases of the call arguments.
(I guess 'pass by object' is a good name).
Well, I'm not sure why that would be. What you've just described is
called "pass by value" in every other language.
I would say that an oject is passed, not a reference.
That seems to contradict the actual behavior, as well as what you said
yourself above. The only way I know how to interpret "an object is
passed" is "the data of that object is copied onto the stack". But of
course that's not what happens. What actually happens is what you
said above: a name (reference) is assigned to the object. The name is
a reference; it is made to refer to the same thing that the argument
(actual parameter) referred to. This is exactly what "the reference
is passed" means, nothing more or less.
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.
You don't need this to decide. This is what happens:
x = Bar() # Call this new Bar object 'x'
In other words, make 'x' refer to this new object.
foo(x) # call function foo with argument the object known as 'x'
Yes. But what does that mean? Does the parameter within 'foo' become
an alias of x, or a copy of it? That's what we DO need to decide.
# Now, in foo:
def foo(x): # Call 'x' locally the object passed to foo
I think you mean here that local 'x' is made to refer to the object
passed to foo. Agreed. It is NOT an alias of the actual parameter.
And that's what we need to know. So it's not call-by-reference, it's
call-by-value; the value of x (a reference to whatever object Bar()
returned) is copied from the value of the parameter (a reference to
that same object, of course).
x = Foo() # Call 'x' locally this new Foo object.
Make 'x' refer to the new Foo() result, yes.
Obviously after all this, 'x' is still the name of the Bar object
created at the start.
Obvious only once you've determined that Python is call-by-value. If
it were like FORTRAN, where everything is call-by-reference, then that
wouldn't be the case at all; the assignment within the function would
affect the variable (or name, if you prefer) passed in.
To sum up: for 'pass by value' to make sense in Python you need to
create an unnecessarily complex model of how Python works.
I have to disagree. The model is simple, self-consistent, and
consistent with all other languages. It's making up terms and trying
to justify them and get out of the logical knots (such as your claim
above that the object itself is passed to a method) that is
unnecessarily complex.
By letting go of 'pass by value' you can simplify your model of the
language
(keeping it correct of course) and it fits in your brain more easily.
I'm afraid I don't see that.
Of course your own model is valid but there is a better one which is
easier to grasp for people without a background in C/C++ - like
languages.
Well, if by C/C++-like languages, you mean also Java, VB.NET, and so
on, then maybe you're right -- perhaps my view is colored by my
experience with those. But alternatively, perhaps there are enough
Python users without experience in other OOP languages, that the
standard terminology was unfamiliar to them, and they made up their
own, resulting in the current linguistic mess.
Best,
- Joe
--
http://mail.python.org/mailman/listinfo/python-list