On Oct 17, 2008, at 2:36 PM, Steve Holden wrote:
No, a "by ref" parameter would mean that this:
def foo(ByRef x):
x = x + [42]
a = [1,2,3]
foo(a)
...would result in a = [1,2,3,42].
In [8]: def foo(x):
...: x += [42]
...:
In [9]: a = [1, 2, 3]
In [10]: foo(a)
In [11]: a
Out[11]: [1, 2, 3, 42]
This demonstrates that lists are mutable, and that += is a mutating
operator (and NOT an assignment).
In [12]: def ffoo(x):
....: x.append(43)
....:
In [13]: ffoo(a)
In [14]: a
Out[14]: [1, 2, 3, 42, 43]
Ditto (but for the .append method).
In [15]: def fffoo(a):
....: a = a + [42]
....:
In [16]: fffoo(a)
In [17]: a
Out[17]: [1, 2, 3, 42, 43]
And here, you're doing an assignment -- this is the only test of the
three that tests whether the parameter is passed by reference or by
value. The result: it's by value.
So, is it call by reference or not?
Not.
Does that depend on the implementation of specific operators?
No.
You problem seems to be that you ar still stuck with the notion of a
name as a reference to a specific area of memory. Which it's not,
excepting only if you want to consider the area of memory that holds a
reference to some value.
Which is exactly what it is, so that's what you should consider.
And my real point is that this is exactly the same as in every other
modern language. Nothing unusual here at all (except that some of us
here seem to want to make up new terminology for standard behavior,
perhaps in order to make Python seem more exotic).
In the case of lists,
a = a + [something]
rebinds a
In standard terminology, it assigns a new value to a.
while
a += [something]
doesn't.
Correct.
So where does that leave you?
In exactly the same happy boat as Java, RB, .NET, etc. (even C++ if
you consider an object pointer to be the equivalent of an object
reference).
Or, use of one of the compound operators like +=. That's the only
real
"gotcha" in Python to somebody coming from another language; you
might
naively expect that x += y is the same as x = x+y, but in Python
this is
not generally the case; instead += is a mutation operator, like the
examples you show above.
Be careful though:
In [18]: a = 42
In [19]: id(a)
Out[19]: 14237932
In [20]: a += 1
In [21]: id(a)
Out[21]: 14237920
Good point -- obviously += can't mutate an immutable type. In those
cases it IS equivalent to an assignment. I can certainly see why
these operators can trip people up at first.
It's the exact same thing. (And exactly the same as in any other
language.)
If you mean it's a reference assigment, of course it is. That's what
he
was trying to say (I believe). But in C, for example,
int i;
i = 42;
actually stores the value 42 in the location associated with the
name c.
Yes, but let's get away from numbers, since those are a bit of a
special case, and not where the argument is revolving. (Since
Python's number-wrappers are immutable, they are behaviorally
equivalent to raw values, and so it really doesn't matter whether you
know that they're actually objects or not).
The discussion at hand is how best to explain and understand mutable
types. I don't remember C too well, but in C++ that'd be something
like:
Foo *x;
x = FooFactory();
This stores the address of the object FooFactory builds into x. It's
equivalent to what Python does with
x = FooFactory()
...except, of course, that Python's syntax is cleaner, and you don't
have all the rope that C/C++ gives you with which to shoot yourself in
the foot.
Hey, I remember Pascal... that was the language used on the Apple
IIGS,
back when I was in junior high. I also remember spending $800 for a
40MB hard drive for it. Ah, those were the days!
40 Mb! You were lucky! Etc., etc., [drools into beard.]
:)
Python's assignment semantics (as opposed to its "object handling, a
term for which I have no referent) are not the same as those of, say
C.
They are, though. The only difference you've pointed out is that
*numbers* are different in Python vs. C, and that's an internal
implementation detail I was blissfully unaware of until this
discussion. (I'm grateful to know it, but it really doesn't matter in
day-to-day coding.)
I believe they are pretty much the same ass those of Icon, another
non-standard interpreted language.
They're also the same as RB, Java, .NET... I'm hoping somebody who
knows some other modern OOP language (e.g. Ruby) will weigh in,
because I bet it's the same as those too.
Comparing it to C isn't really fair, because C isn't even an OOP
language. C++ would at least be in the same ballpark.
There are close similarities between Python's names and C reference
variables, but the semantics are not exactly parallel.
I agree; reference variables are an odd beast, most commonly used (and
most similar to) a ByRef parameter in modern languages. And it seems
that Python simply doesn't have that.
People here don't describe Python as different just because they
*want*
it to be different. Python acknowledges intellectual debts to many
languages, none of which is exactly like it.
Sure, nothing's exactly like it in all ways. But its object handling
[*] is, in fact, exactly like every other modern OOP language.
Best,
- Joe
[*] Object handling: the ways in which objects are created, stored,
referenced, assigned, and passed into and out of method calls.
--
http://mail.python.org/mailman/listinfo/python-list