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

Reply via email to