Finding the instance reference of an object [long and probably boring]

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Fri Nov 7 12:29:52 EST 2008


On Fri, 07 Nov 2008 08:48:19 -0700, Joe Strout wrote:

> I think of it this way: every variable is an object reference; no
> special syntax needed for it because that's the only type of variable
> there is.  (Just as with Java or .NET, when dealing with any class type;
> Python is just a little more extreme in that even simple things like
> numbers are wrapped in objects.)
> 
> Note: I tried to say "name" above instead of "variable" but I couldn't
> bring myself to do it -- "name" seems to generic to do that job.  Lots
> of things have names that are not variables: modules have names, classes
> have names, methods have names, and so do variables.

But modules, classes and methods are also objects, and they can be bound 
to names.

What's the name of the module after this piece of code?

import math
foo = math
del math


Unfortunately, the term "name" is *slightly* ambiguous in Python. There 
are names, and then there are objects which have a name attribute, which 
holds a string. This attribute is usually called __name__ but sometimes 
it's called other things, like func_name.

The __name__ attribute of objects is an arbitrary label that the object 
uses for display purposes. But names are the entities that Python code 
usually uses to refer to objects.


[...]
> what  
> argument is there that the Python community should use its own unique  
> terminology for concepts that apply equally well to other languages?   
> Wouldn't communication be easier and smoother if we adopted standard  
> terms for standard behavior?

You're assuming that call-by-sharing isn't a standard term. That's not 
true. It's a standard term that is sadly not well known, I believe 
because of the ignorance of most coders to the history of their own 
discipline. (I include myself in that.)

You're also assuming that the use of "call-by-value" to refer to very 
different behaviours in C and Java somehow makes communication easier and 
smoother. I don't think it does.


[...]
> In a language that supports  
> integers and doubles as simple types, stored directly in a variable,  
> then it is an obvious generalization that in the case of an object  
> type, the value is a reference to an object.

How is it a generalization?

Using Python syntax instead of Java, but let's pretend that Python ints 
are primitives just like in Java, but floats are not. I do this to avoid 
any confusion over mutable/immutable, or container types. Nice simple 
values, except one is an object and one is a primitive type.

x = 1  # the value of x is 1
x = 1.0  # the value of x is 0x34a5f0

Where is the generalization that you speak of? In a generalization, you 
extend the same rule to cover slightly different circumstances. But 
that's not what happens here. In the first place, you start with the rule 
that the value of x is the thing you assign to x. In the second place, 
you change the rule to say that the value of x is an arbitrary 
implementation-dependent pointer to the thing you assign to x. That's not 
a generalization, it's an anti-generalization.


> But Python doesn't have those simple types, so there is a temptation  
> to try to skip this generalization and say that references are not  
> values, but rather the values are the objects themselves (despite the  
> dereferencing step that is still required to get any data out of  
> them).

What dereferencing step? There's no such thing in Python code. You just 
use the name, as normal.

Oh sure, at the deep implementation level there's a dereferencing step, 
but that applies for primitive types in C too. When you refer to a 
variable x in C, the CPU has to look into a memory location to find out 
what the value of x is. That applies whether x is an int on the stack or 
a object in the heap. But it's not something that the C programmer has to 
worry about, it's an implementation detail handled by the compiler and 
the runtime environment. It's not part of your C program.

In the same way the dereferencing of Python names is not part of your 
Python program. It's an implementation detail.


> However, it seems to me that when you start denying that the value of  
> an object reference is a reference to an object, this is when you get  
> led into a quagmire of contradictions.

Let's hear some of these contradictions.

Personally, they would have to be pretty big to make me give up saying 
that the value of x after x=1 is 1.


[...]
> But continuing to attempt to gloss over that fact, when you come to  
> parameter passing, you're then stuck trying to avoid describing it as  
> call by value, since if you claim that what a variable contains is the  
> object itself, then that doesn't fit (since clearly the object itself  
> is not copied).

Your reasoning is backwards. Call-by-value by definition implies that the 
value is copied. If the value isn't copied, it can't be call-by-value. 
You shouldn't change the definition of "value" in order to hammer the 
square peg of your language into the round hole of "call-by-value", 
especially since there has been a perfectly fine alternative name for the 
behaviour since at least 1974.

What the Java and VB.NET communities have essentially done is redefine 
"horse" to mean "internal combustion engine" simply to avoid accepting 
that there are such things as horseless carriages.


> You also have to describe the assignment operator as  
> different from all other languages, since clearly that's not copying  
> the object either.

A slight pedantic note: Python doesn't have an assignment operator, it is 
a statement. You can't override assignment in Python.

*If* somebody reliably told me that assignment in "all other 
languages" (what, Forth, Lisp, Brainf*ck, Intercal, Algol-60, Ruby, *all* 
of them???) meant copying, then I'd quite happily accept that Python 
assignment is different, since it clearly doesn't copy the value. 
Assignment in Python operates on *names*, not objects. "x=y" means 
"change the name 'x' so that it refers to the current value of 'y'", not 
copy the value of y to x.



> So, while I'm trying this path on for size (and will continue to mull  
> it over further), please try on this approach: boldly admit that  
> they're [variables] references, and embrace that fact.

Why on earth would I want to give up saying that the value of x after x=1 
is 1 just to satisfy people who can't cope with the existence of 
horseless carriages?


> Perhaps we could  
> round up 20 newbies, divide them into two groups of 10, give each one  
> a 1-page explanation either based on passing object references by- 
> value, or passing values sort-of-kind-of-by-reference, and then check  
> their comprehension by predicting the output of some code snippets.   
> That'd be very interesting.  It's hard for me to believe that the  
> glossing-over-references approach really is easier for anybody, but  
> maybe I'm wrong.

Well Joe, you've seen for yourself at least one person in this thread 
read YOUR explanation of Python's behaviour and conclude from that that 
Python is call-by-reference.

Then there's these:

"I was under the assumption that everything in python was a reference.
So if I code this: ... I though the contents of lst would be modified."

http://mail.python.org/pipermail/python-list/2006-January/360222.html


"Python passes references to objects by value (like Java), and everything 
in Python is an object. This sounds simple, but then you will notice that 
some data types seem to exhibit pass-by-value characteristics, while 
others seem to act like pass-by-reference... what's the deal?"

http://www.goldb.org/goldblog/CommentView,guid,4eb92070-c279-44b3-
ac2a-5d1c4f3e8115.aspx

(The deal is, p-b-v and p-b-r are not the only two choices.)


And here:

"Python passes all arguments using 'pass by reference'."

http://www.penzilla.net/tutorials/python/functions/


And from the one thread:

"Python uses bog standard call-by-reference" -- Nick Maclaren,
University of Cambridge Computing Service:
http://mail.python.org/pipermail/python-list/2000-April/030077.html

"I would describe Python parameter passing as call-by-value, with the 
wrinkle that the value being passed is always a reference to an object." 
-- Greg Ewing, Computer Science Dept, University of Canterbury (NZ)
http://mail.python.org/pipermail/python-list/2000-April/030315.html



-- 
Steven



More information about the Python-list mailing list