Question about Pass-by-object-reference?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed Jul 23 23:22:16 EDT 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:

    some_function([])

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“.

http://effbot.org/zone/call-by-object.htm

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:

http://javadude.com/articles/passbyvalue.htm


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*.)


-- 
Steven



More information about the Python-list mailing list