Question about Pass-by-object-reference?
steve+comp.lang.python at pearwood.info
Thu Jul 24 05:22:16 CEST 2014
On Wed, 23 Jul 2014 18:51:47 -0400, Terry Reedy wrote:
> On 7/23/2014 1:35 AM, Steven D'Aprano wrote:
>> On Wed, 23 Jul 2014 11:59:45 +1000, Ben Finney wrote:
>>> fl <rxjwg98 at gmail.com> writes:
>>>> On Tuesday, July 22, 2014 8:27:15 PM UTC-4, Terry Reedy wrote:
>>> The point being made is that no values are is “passed” in a function
>>> call. If you have learned that term from elsewhere, it doesn't apply
>>> sensibly to Python.
>> Hmmm. I don't know that I like that. I think that these two sentences
>> mean the same thing:
>> "Call the function with x as argument."
>> "Pass x to the function."
> I disagree. In Python, when one calls the function with an argument,
> computer implementatipns 'pass' an object reference,
Terry, while I appreciate that you are trying to prevent confusion, I
think you're actually causing even more confusion than what you are
arguing against. Starting with yourself.
I stated that "call function with argument x" and "pass x to function"
mean the same thing. You said that you disagree, and then the very next
sentence you link the two concepts together: when you call a function
with an argument, the computer passes something to the function in some
manner. By your own description, one implies the other. If not, then I'd
like to see an example of a programming language where you can have one
without the other.
I respectfully disagree with you and Ben Finney on this matter. I think
that the plain English meanings of the two sentences will be understood
as the same thing by any English speaker old enough to have learned about
functions (in mathematics or computing), and that there is no harm in
this any more than it is harmful to treat these as the same:
"I went for a stroll by the river."
"I took a leisurely walk along the river."
> which in CPython is an object address.
If we're talking CPython implementation, then surely it passes a pointer,
which is an abstract data type and not necessarily just an address.
(Pointers in most languages that have them also have a type, not just a
value.) But that's just a niggle.
> Conflating the two sentences above leads people to
> claim that python 'calls by (object) reference'. In a sense, it does,
> But thinking in those terms often leads to false inferences about how
> Python behaves. So I think it better not to think is such terms.
I don't agree that this is the cause of the problem. As I've stated many
times now, I believe that the problem is that people believe that there
are only two argument passing conventions, pass by value and pass by
reference. Do you think it helps matters one iota if we refer to them as
"call by value" and "call by reference" instead of "pass ..."?
I've never found anyone claiming that Python is call by name, even though
the semantics of call by name are very similar to those of call by
reference. I'd even argue that call by name is a *better* fit (still
wrong, but not quite as wrong) as call by reference: the difference being
that in call by reference semantics, the argument cannot be a literal, so
we could not write this:
but (as I understand it) with call by name semantics, you can. But
because call by name is less well known than call by reference, people
don't suggest it.
By the way, you refer to "call by object reference" as being a wrong
inference. I think your terminology is messed up, and if you want to
argue I suggest you take it up with the Effbot:
The most accurate description is CLU’s “call by object” or “call
by sharing“. Or, if you prefer, “call by object reference“.
Call by object reference would be a good name for what Python does (since
it actually is what CPython does), if not for the unfortunate fact that
if you drop the word "object" it leaves "call by reference", which of
course is a different calling convention with well-defined, and very
different, semantics. So I prefer "call by object" or "call by sharing".
But regardless of which name is used, we agree that that's what Python
does (as well as Ruby and Java and others). This article:
is a remarkable (and popular!) example of the confusion. Despite spending
some time at the end of the article inventing his own terminology "pass
by memento" and "pass by proxy" for remote method calls [and I'll get to
them in a minute], the author spends the whole discussion implicitly
assuming that call by value and call by reference are the only two ways
that you can pass arguments to a function. This leads him to the
remarkable conclusion that if you create a Dog instance and bind it a
name myDog (in Java: Dog myDog; in Python, myDog = Dog()) the actual
value of myDog is not the instance but some memory address, say 42.
You have to be very clever to be that stupid.
As Fredrik Lundh (the Effbot) wrote:
well, I guess you can, in theory, value an artificial number
assigned to an object as much as the object itself.
"Joe, I think our son might be lost in the woods"
"Don't worry, I have his social security number"
The claim that myDog is actually a memory address is also factually
incorrect (the author acknowledges this in a parenthetical aside, but I'm
not going to let that get in the way of a good rant). Since the Java
garbage collector can move blocks of memory around, a simple address
isn't enough, it needs to be an indirect address managed by the garbage
collector. Possibly something like what classic Mac OS called a handle.
As far as as his "call by memento", from the description that is
*exactly* the same semantics as call by value, the only difference being
that "copy the value" in this case requires serialising it and sending it
across the network instead of merely copying bytes in memory. And his
"call by proxy" sounds exactly like call by object except (again) the
implementation requires using a proxy which references back to the
original object. That is, it's an object reference, just not a managed
pointer. All of which implies that Java's remote method calls use exactly
the same argument passing strategy as it's non-remote method calls.
(You'll note I say the same *strategy*, not the same *implementation*.)
More information about the Python-list