Re: Finding the instance reference of an object

2008-11-19 Thread Douglas Alan
greg [EMAIL PROTECTED] writes:

 Steven D'Aprano wrote:

 At least some sections of the Java community seem to prefer a
 misleading and confusing use of the word value over clarity and
 simplicity, but I for one do not agree with them.

 I don't see anything inherently confusing or misleading
 about it. Confusion only arises when some people jump up
 and say that it's wrong to use the terms that way, because
 it might cause confusion...

Personally, I find this whole debate kind of silly, as it is based on
a completely fallacious either/or dichotomy.

(1) It is unarguably true that Python and Java use a type of
call-by-value.  This follows from the standard definition of
call-by-value, and common usage in, for example, the Scheme and
Java communities, etc.

(2) It is also unarguably true that saying that Python or Java use
call-by-value, and saying nothing more is going to be profoundly
confusing to anyone who is learning these languages.

It's like the difference between

   Q. What is a giraffe?

   A. A giraffe is a type of animal.

and

   Q. What is Greg?

   A. Greg is a type of animal.

In both cases, the answers are strictly correct, but in the second
case, the answer is also deeply misleading.

Q. How do we generally solve this problem when speaking?

A. We invent more specific terms and then generally stick to the more
specific terms when the more general terms would be misleading.

I.e.,

   Q. What is Greg?

   A. Greg is a human being.

and

   Q. What type of calling semantics do Python and Java use?

   A. Call-by-sharing.

I assert that anyone who does not understand all of the above, is
helping to spread confusion.

|oug
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-19 Thread Joe Strout

On Nov 19, 2008, at 11:05 AM, Douglas Alan wrote:


Personally, I find this whole debate kind of silly, as it is based on
a completely fallacious either/or dichotomy.

(1) It is unarguably true that Python and Java use a type of
   call-by-value.  This follows from the standard definition of
   call-by-value, and common usage in, for example, the Scheme and
   Java communities, etc.


True.


(2) It is also unarguably true that saying that Python or Java use
   call-by-value, and saying nothing more is going to be profoundly
   confusing to anyone who is learning these languages.


Perhaps (unless they've already learned this from one of the other  
languages).



Q. How do we generally solve this problem when speaking?

A. We invent more specific terms and then generally stick to the more
specific terms when the more general terms would be misleading.

I.e.,

  Q. What is Greg?

  A. Greg is a human being.

and

  Q. What type of calling semantics do Python and Java use?

  A. Call-by-sharing.


Fair enough, but if the questioner then says WTF is call-by-sharing,  
we should answer call-by-sharing is the term we prefer for call-by- 
value in the case where the value is an object reference (as is always  
the case in Python).



I assert that anyone who does not understand all of the above, is
helping to spread confusion.


I agree.

Best,
- Joe

--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-19 Thread Craig Allen
I've just come to the conclusion it's not possible to call functions
in python, to do so is undefined and indeterminate, like dividing by
zero.  Henceforth no calling functions for me as clearly it's the
devil's playground.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-19 Thread Aaron Brady
On Nov 19, 12:28 pm, Joe Strout [EMAIL PROTECTED] wrote:
 On Nov 19, 2008, at 11:05 AM, Douglas Alan wrote:
  (2) It is also unarguably true that saying that Python or Java use
     call-by-value, and saying nothing more is going to be profoundly
     confusing to anyone who is learning these languages.

 Perhaps (unless they've already learned this from one of the other  
 languages).

If they learn the bad definition first, we can't go back and change
it.  We can correct it for them for the future.  Don't appeal to hot-
shot authorities, like the ones that don't acknowledge that there were
already people using terms they hijacked for their own cult following.

    Q. What type of calling semantics do Python and Java use?

    A. Call-by-sharing.

 Fair enough, but if the questioner then says WTF is call-by-sharing,  
 we should answer call-by-sharing is the term we prefer for call-by-
 value in the case where the value is an object reference (as is always  
 the case in Python).

But if someone says, 'What is call-by-reference?', do you answer, 'C-b-
r is the term we prefer for call-by-value in the case where the value
is a variable reference'?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-19 Thread Douglas Alan
Joe Strout [EMAIL PROTECTED] writes:

   Q. What type of calling semantics do Python and Java use?

   A. Call-by-sharing.

 Fair enough, but if the questioner then says WTF is call-by-sharing,
 we should answer call-by-sharing is the term we prefer for call-by-
 value in the case where the value is an object reference (as is always
 the case in Python).

Personally, I think that it is much preferable to leave
call-by-value completely out of any such discussion, as it provably
leads to a great deal of confusion and endless, pointless debate.
It's better to just start from a clean slate and explain how
call-by-sharing works, and to assert that it is quite different from
the calling semantics of languages such as C or Pascal or Fortran, so
the student must set aside any preconceptions about how argument
passing works.

Call-by-sharing is technically a type of call-by-value only for those
who are devotees of academic programming language zoology.  For
everyone else, call-by-sharing is its own beast.  One might point all
of this out in the discussion, however, if it will help the other
person understand.  You never know -- they might be a fan of academic
programming zoology.

|oug
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-12 Thread Craig Allen

 arguably even older than that to Lisp.


Firstly, thanks to those that have responded to my part in this
debate, I have found it very informative and interesting as I have the
entire thread.  However, with regard to comments that I led myself
astray, I want to reiterate the one thing I find determinably
important in this... I did not go astray because I did not fret what
the words meant and try to draw anything from that. I learned exactly
what would happen when I passed arguments different ways, and I
learned that well and accurately. Then I mused what to call it all. At
no time was I astray because I think to really be astray would be to
have a misunderstanding on what happens, not on what we call what
happens.

but I will concede that trying to use call-by-name is not a viable
idea as it's yet another term that is already taken. I did not think
too hard what the distinction is, and as far as I know it's as good a
candidate for what we call it as anything else, but I certainly don't
want to fight for the term.  Whatever we call the passing semantics
and methods in Python... it will not change what I understand about
what happens with certain kinds of calls vs others.

cheers.
--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-11 Thread Steve Holden
greg wrote:
 Arnaud Delobelle wrote:
 But in the course of conversation I might refer to
 Napoleon, meaning Napoleon Bonaparte (1769 - 1821) or Napoleon III (1808
 - 1873).
 
 That's more like referring to the name 'Napoleon' in
 two different namespaces. The original binding still
 exists, you're just switching contexts.
 
 My point was to get away from a model for Python which was built on its
 likely implementation and to hint that we can build one using the naive
 concept of 'name for a thing' instead.
 
 I don't believe it's possible to build any complete and
 correct model of Python behaviour without including some
 concept equivalent to a reference.
 
 You can talk about names written on PostIt notes and
 such like, but that only gets you a short way. It doesn't
 easily handle names in different namespaces, or references
 that exist without simple names, e.g. list and tuple
 items. Trying to repair these deficiencies only leads to
 increasingly bizarre and contrived mental pictures.
 
+1

 On the other hand, if you explicitly include the concept
 of a reference from the beginning, everything is quite
 clear and consistent.
 
Yes. References do explain things very well, since the model is in exact
agreement with the reality of the implementation.

 In other words, the model should be as simple as possible
 but no simpler. Leaving out references makes it too
 simple.
 
 Another point I'd like to make is that there is nothing
 inherently low-level about the concept of a reference.
 It doesn't have to be implemented as a memory address or
 any other particular machine-level thing. It's possible to
 talk about Python object references in a completely
 implementation-independent way.
 
Indeed one might make use of some object store, and references would
still be useful even if they weren't memory addresses.

 Also, just because you don't explicitly refer to them and
 manipulate them at the language level doesn't mean they
 don't exist. To think otherwise is like thinking that air
 doesn't exist just because you can't see it. There are
 plenty of experiments which clearly indicate its existence.
 Likewise, there are plenty of experiments that you can
 perform with any Python interpreter that reveal the
 existence of references, or something equivalent to them.
 
Good stuff. I have come to the conclusion that this thread is mostly
best left alone, since the remaining participants appear to have agreed
on Python's semantics and now continue to argue about what name should
be used to describe them.

regards
 Steve
-- 
Steve Holden+1 571 484 6266   +1 800 494 3119
Holden Web LLC  http://www.holdenweb.com/

--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-11 Thread greg

Steven D'Aprano wrote:

If you equate arguments within the called procedure to the *name* of 
the arguments, then changing the arguments would mean changing the NAME


If changing the name means rebinding the name,
then I agree -- that's exactly the point I was trying to
make.

If you equate value with object, as you suggested some posts ago, 


*I* didn't suggest that, someone else did. I was just
pointing out that you can use the word that way if you
want, as long as you're consistent about it. And being
consistent means using it in the same way when talking
about assignment and about by-value parameter passing.
If you insist that one of these implies copying the
value but the other doesn't, then you're being
inconsistent.

At least some sections of the Java community seem to prefer a misleading 
and confusing use of the word value over clarity and simplicity, but I 
for one do not agree with them.


I don't see anything inherently confusing or misleading
about it. Confusion only arises when some people jump up
and say that it's wrong to use the terms that way, because
it might cause confusion...

In the general case, you can't emulate call-by-reference by passing a 
name, because you don't know what the name of an object is.


That's true, you need to communicate the namespace as
well, either implicitly or explicitly. So a
(namespace, name) pair, or a (sequence, index) pair
in the case of a sequence item, would be the equivalent
of a reference in the sense meant by call by reference.

--
Greg

--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-10 Thread Terry Reedy

greg wrote:

Arnaud Delobelle wrote:


(CBV) An evaluation strategy where arguments are evaluated before
the function or procedure is entered. Only the values of the
arguments are passed and changes to the arguments within the called
procedure have no effect on the actual arguments as seen by the
caller.


That hinges on what exactly is meant by changes to
the arguments.


Mutating them, like Python does, which is why calling Python CBV leads 
people to write buggy code.


In Python it can only mean assigning

directly to the bare name -- anything else isn't
changing the argument itself, but something else to
which the argument refers.


Hogwash.  The argument is the object and mutable objects can be changed 
as seen by the caller.



--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-10 Thread greg

Terry Reedy wrote:

In other words, as I acknowledged in my other post, one can say that all 
calling is calling by value.


No, those are not other words for what I'm saying.
Call by reference is very demonstrably different
from call by value, as has been pointed out a large
number of times already.

--
Greg
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-10 Thread Joe Strout

On Nov 10, 2008, at 8:30 AM, Terry Reedy wrote:


That hinges on what exactly is meant by changes to
the arguments.


Mutating them, like Python does, which is why calling Python CBV  
leads people to write buggy code.


In Python it can only mean assigning

directly to the bare name -- anything else isn't
changing the argument itself, but something else to
which the argument refers.


Hogwash.  The argument is the object and mutable objects can be  
changed as seen by the caller.


By that definition, Java, REALbasic, C++, and VB.NET are all call-by- 
reference too (even when explicitly using the ByVal keyword in RB/ 
VB.NET).  This will come as quite a shock to the designers and users  
of those languages.


For what it's worth, I think Greg (double-quoted above) has it exactly  
right.  The argument in any of these languages is an object reference;  
changing the object and changing the object reference are two  
different things.


Best,
- Joe

--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-10 Thread greg

Arnaud Delobelle wrote:


// What is passed to foo below is obviously not a 'variable
// reference' as the argument is not a variable.
foo(a[3]); // Now a[3] == 7
foo(b.i);  // Now b.i == 7


Yes, it is. By variable I mean what C calls an lvalue,
i.e. something you can assign to.


I'm not sure that your definition of 'call by value' is widely
accepted.  If it was, then this thread wouldn't exist.


It seems to be accepted by the Java and VB community,
judging by what they refer to as call-by-value in those
languages.

You won't necessarily find it written down anywhere in
the exact words I used. I have reverse-engineered it
from the characteristics of a wide variety of languages
that use the term call-by-value to describe one of their
parameter passing mechanisms. Think of it as a theory
that fits the observed linguistic facts.


(CBV) An evaluation strategy where arguments are evaluated before
the function or procedure is entered. Only the values of the
arguments are passed and changes to the arguments within the called
procedure have no effect on the actual arguments as seen by the
caller.


That hinges on what exactly is meant by changes to
the arguments. In Python it can only mean assigning
directly to the bare name -- anything else isn't
changing the argument itself, but something else to
which the argument refers.

--
Greg
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-10 Thread Terry Reedy

Joe Strout wrote:

On Nov 10, 2008, at 8:30 AM, Terry Reedy wrote:


That hinges on what exactly is meant by changes to
the arguments.


Mutating them, like Python does, which is why calling Python CBV leads 
people to write buggy code.


In Python it can only mean assigning

directly to the bare name -- anything else isn't
changing the argument itself, but something else to
which the argument refers.


Hogwash.  The argument is the object and mutable objects can be 
changed as seen by the caller.


By that definition, Java, REALbasic, C++, and VB.NET are all 
call-by-reference too (even when explicitly using the ByVal keyword in 
RB/VB.NET).  This will come as quite a shock to the designers and users 
of those languages.


For what it's worth, I think Greg (double-quoted above) has it exactly 
right.  The argument in any of these languages is an object reference; 
changing the object and changing the object reference are two different 
things.


--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-10 Thread Terry Reedy

Joe Strout wrote:

On Nov 10, 2008, at 8:30 AM, Terry Reedy wrote:


That hinges on what exactly is meant by changes to
the arguments.


Mutating them, like Python does, which is why calling Python CBV leads 
people to write buggy code.


In Python it can only mean assigning

directly to the bare name -- anything else isn't
changing the argument itself, but something else to
which the argument refers.


Hogwash.  The argument is the object and mutable objects can be 
changed as seen by the caller.


By that definition, Java, REALbasic, C++, and VB.NET are all 
call-by-reference too (even when explicitly using the ByVal keyword in 
RB/VB.NET).  This will come as quite a shock to the designers and users 
of those languages.


For what it's worth, I think Greg (double-quoted above) has it exactly 
right.  The argument in any of these languages is an object reference; 


In the Python I am talking about, the language defined in the Python 
Reference Manual, arguments are objects.


Bye,

tjr


--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-10 Thread Aaron Brady
On Nov 7, 3:03 pm, Arnaud Delobelle [EMAIL PROTECTED] wrote:
 1. Is Napoleon a copy of Dobby or are they the same cat?

 2. Is Polion a copy of Napoleon or are they the same cat?

 3. When we got rid of Napoleon's fleas, was Nelson deflea-ed as well?

 4. When Napoleon died, did Nelson die as well?

 5. When we got a new Napoleon, does this mean that our neighbours got a
    new Nelson?

 Now a question about the questions about the story:

    To be able to understand the story and answer questions 1-5, do we
    need to think of Napoleon, Nelson and Polion as variables containing
    references to cat objects, or is it enough to think of them as three
    names for cats?

Do you ever say to someone, 'Napoleon' will no longer refer to
Nelson.  It is this lobster now instead, while you are holding a
lobster?

My point is that the assignment operation is rare in natural language.

Some examples:

unitedstates.president= people['Barack Obama']
catholicchurch.pope= people['Joseph Ratzinger']
chicagocubs.manager= people['Lou Pienella']

That is, in January, 'The President' will start to refer to a
different person.  But you don't see:

popstars['Britney Spears']= people['Ricky Martin']
people['Richard Nixon']= people['Ronald Reagan']

You also have expressions, such as 'the man in the corner drinking
Coke' and 'the first street on the right', which would not be likely
to be modeled as attributes, per se, such as:

corner.men.drinking['Coke']
street.ontheright[0]

You'd more likely use:

select id from people where standingin = 'corner' and drinking =
'coke'
select id from streets where distanceonright =
min( distanceonright )

Maybe in the future we'll see relational code, rather than
hierarchical subclasses:

 select fly from birds where name = 'bluejay'
'flap_wings()'
 select fly from birds where name = 'ostrich'
'raise CannotFlyException'
--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-10 Thread Arnaud Delobelle
Aaron Brady [EMAIL PROTECTED] writes:

 Do you ever say to someone, 'Napoleon' will no longer refer to
 Nelson.  It is this lobster now instead, while you are holding a
 lobster?

Not explicitly.  But in the course of conversation I might refer to
Napoleon, meaning Napoleon Bonaparte (1769 - 1821) or Napoleon III (1808
- 1873).  There would then be an implicit 'rebinding' of the name Napoleon.

 My point is that the assignment operation is rare in natural language.

My point was to get away from a model for Python which was built on its
likely implementation and to hint that we can build one using the naive
concept of 'name for a thing' instead.  IOW, 'call by value' is an
unnecessary obfuscation of what *actually* happens (even though it may
describe accurately the artifacts employed by an implementation)

I'm glad that you thought about it!

-- 
Arnaud
--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-10 Thread Aaron Brady
On Nov 10, 2:45 pm, Arnaud Delobelle [EMAIL PROTECTED] wrote:
 Aaron Brady [EMAIL PROTECTED] writes:
  Do you ever say to someone, 'Napoleon' will no longer refer to
  Nelson.  It is this lobster now instead, while you are holding a
  lobster?

 Not explicitly.  But in the course of conversation I might refer to
 Napoleon, meaning Napoleon Bonaparte (1769 - 1821) or Napoleon III (1808
 - 1873).  There would then be an implicit 'rebinding' of the name Napoleon.

  My point is that the assignment operation is rare in natural language.

 My point was to get away from a model for Python which was built on its
 likely implementation and to hint that we can build one using the naive
 concept of 'name for a thing' instead.  IOW, 'call by value' is an
 unnecessary obfuscation of what *actually* happens (even though it may
 describe accurately the artifacts employed by an implementation)

 I'm glad that you thought about it!

I agree with Terry that all calling is call-by-value, and Steven that
all calling is call-by-bit-flipping.  I agree with Joe that call-by-
object is a special case of call-by-value.

I thought of another way Python's passing method could be
implemented.  Parameters are passed as namespace-name pairs, and every
time a variable occurs, it's looked up in the namespace it's in.  If
it's changed (concurrently) in the outer scope, a copy is made into
the inner scope.  If it's changed in the inner scope, a new entry is
added there.

It's still call-by-value (and bit-flipping) on some level, in the
trivial sense.  What else is it?

--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-10 Thread Joe Strout

On Nov 10, 2008, at 2:30 PM, Aaron Brady wrote:


I agree with Terry that all calling is call-by-value, and Steven that
all calling is call-by-bit-flipping.  I agree with Joe that call-by-
object is a special case of call-by-value.


Woo!  Almost sounds like approaching consensus.  :)

However, I'm sorry to say that I think both Terry's and Steven's  
descriptions are unhelpful.  There really are important distinctions  
among parameter evaluation strategies.  Call-by-reference is not call- 
by-value (though it is call-by-bit-flipping, but that's too low a  
level).


But if we can  agree that call-by-sharing (which I believe is the more  
widely documented term than call-by-object) is a special case of  
call-by-value, when the parameters are object references, then I think  
we may have a winner.


Best,
- Joe

--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-10 Thread Steven D'Aprano
On Mon, 10 Nov 2008 08:39:58 -0700, Joe Strout wrote:

 By that definition, Java, REALbasic, C++, and VB.NET are all call-by-
 reference too (even when explicitly using the ByVal keyword in RB/
 VB.NET).

No, they are not call-by-reference either. They are call-by-sharing, just 
like Python and CLU.



-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-10 Thread Steven D'Aprano
On Mon, 10 Nov 2008 23:16:13 +1300, greg wrote:

 (CBV) An evaluation strategy where arguments are evaluated before
 the function or procedure is entered. Only the values of the
 arguments are passed and changes to the arguments within the called
 procedure have no effect on the actual arguments as seen by the
 caller.
 
 That hinges on what exactly is meant by changes to the arguments. In
 Python it can only mean assigning directly to the bare name -- anything
 else isn't changing the argument itself, but something else to which the
 argument refers.

But the name isn't the argument. The argument to a function is an object, 
not a name. You can't write a function in Python that takes a name as an 
argument[1], which would be equivalent to Pascal's var parameters.

Take a function foo that takes one formal parameter x. Pass an actual 
argument y to it. The argument is the object currently bound to y, not 
the name y. Nothing inside foo can rebind the name y because foo doesn't 
see the name y, it sees the object. Rebinding (or deleting) the name x 
inside foo does nothing to the object bound to y, or the name y.






[1] You can pass a string representing the name to a function, which can 
then use some combination of setattr, globals(), exec etc to work with 
the name represented by that string. But you're still passing an object 
to the function, not a name.


-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-10 Thread greg

Arnaud Delobelle wrote:

But in the course of conversation I might refer to
Napoleon, meaning Napoleon Bonaparte (1769 - 1821) or Napoleon III (1808
- 1873).


That's more like referring to the name 'Napoleon' in
two different namespaces. The original binding still
exists, you're just switching contexts.


My point was to get away from a model for Python which was built on its
likely implementation and to hint that we can build one using the naive
concept of 'name for a thing' instead.


I don't believe it's possible to build any complete and
correct model of Python behaviour without including some
concept equivalent to a reference.

You can talk about names written on PostIt notes and
such like, but that only gets you a short way. It doesn't
easily handle names in different namespaces, or references
that exist without simple names, e.g. list and tuple
items. Trying to repair these deficiencies only leads to
increasingly bizarre and contrived mental pictures.

On the other hand, if you explicitly include the concept
of a reference from the beginning, everything is quite
clear and consistent.

In other words, the model should be as simple as possible
but no simpler. Leaving out references makes it too
simple.

Another point I'd like to make is that there is nothing
inherently low-level about the concept of a reference.
It doesn't have to be implemented as a memory address or
any other particular machine-level thing. It's possible to
talk about Python object references in a completely
implementation-independent way.

Also, just because you don't explicitly refer to them and
manipulate them at the language level doesn't mean they
don't exist. To think otherwise is like thinking that air
doesn't exist just because you can't see it. There are
plenty of experiments which clearly indicate its existence.
Likewise, there are plenty of experiments that you can
perform with any Python interpreter that reveal the
existence of references, or something equivalent to them.

--
Greg
--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-10 Thread greg

Aaron Brady wrote:


I thought of another way Python's passing method could be
implemented.  Parameters are passed as namespace-name pairs, and every
time a variable occurs, it's looked up in the namespace it's in.  If
it's changed (concurrently) in the outer scope, a copy is made into
the inner scope.  If it's changed in the inner scope, a new entry is
added there.


That sounds like a kind of copy-on-write. It's certainly not
call-by-value by any sane interpretation (contrary to your
assertion that all calling is call-by-value).

--
Greg
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-10 Thread greg

Steven D'Aprano wrote:


But the name isn't the argument. The argument to a function is an object


The *formal* argument *is* a name, and that's what
the phrase changes to the arguments within the called
procedure is talking about.

Take a function foo that takes one formal parameter x. Pass an actual 
argument y to it. The argument is the object currently bound to y, not 
the name y. Nothing inside foo can rebind the name y because foo doesn't 
see the name y, it sees the object.


More to the point, it sees the *name x* rather than the
name y, and rebinding the name x doesn't change the binding
of name y. Therefore, the name y has been passed by value,
not by reference.

[1] You can pass a string representing the name to a function, which can 
then use some combination of setattr, globals(), exec etc to work with 
the name represented by that string.


This would be the Python equivalent of the strategy used
in C to emulate call-by-reference -- and it's needed for
the same reason, i.e. the language itself only provides
call-by-value. So you pass a value that you can manually
dereference to get the same effect.

--
Greg
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-10 Thread Steven D'Aprano
On Tue, 11 Nov 2008 16:54:10 +1300, greg wrote:

 Steven D'Aprano wrote:
 
 But the name isn't the argument. The argument to a function is an
 object
 
 The *formal* argument *is* a name, and that's what the phrase changes
 to the arguments within the called procedure is talking about.

If you equate arguments within the called procedure to the *name* of 
the arguments, then changing the arguments would mean changing the NAME, 
not the object bound to the name. That is, something like this:

def foo(x):
y = x
del x

except as a single operation. I'm sure that's not what you intended to 
say, but that's what you have said. Except for del and rebinding, Python 
level code does not allow you to do anything to *names*, only to objects. 
But I'm sure you know this, which makes your claim all the more confused.


 Take a function foo that takes one formal parameter x. Pass an actual
 argument y to it. The argument is the object currently bound to y, not
 the name y. Nothing inside foo can rebind the name y because foo
 doesn't see the name y, it sees the object.
 
 More to the point, it sees the *name x* rather than the name y, and
 rebinding the name x doesn't change the binding of name y. Therefore,
 the name y has been passed by value, not by reference.

The term for what you have just said is non sequitor, Latin for it 
does not follow. The _name_ y is not passed AT ALL. If there is a value 
that is passed, it is the object bound to y, and not any name at all.

If you equate value with object, as you suggested some posts ago, 
then it could be argued that Python is call-by-value (for value=object) 
but because call by value has connotations and implications that do not 
apply to Python, we prefer to avoid the misleading and confusing term 
c-b-v in preference to Barbara Liskov's term call by sharing or call 
by object.

At least some sections of the Java community seem to prefer a misleading 
and confusing use of the word value over clarity and simplicity, but I 
for one do not agree with them.

 

 [1] You can pass a string representing the name to a function, which
 can then use some combination of setattr, globals(), exec etc to work
 with the name represented by that string.
 
 This would be the Python equivalent of the strategy used in C to emulate
 call-by-reference -- and it's needed for the same reason, i.e. the
 language itself only provides call-by-value. So you pass a value that
 you can manually dereference to get the same effect.

In the general case, you can't emulate call-by-reference by passing a 
name, because you don't know what the name of an object is. Obviously I 
can hard-code some names:

def swap(x, y):
# arguments x and y are actually pointless
g = globals()
g['x'], g['y'] = g['y'], g['x']


but you can't emulate c-b-r's ability to swap arbitrary names determined 
by the compiler. The reason is that when you call a function with an 
argument, the function sees only the object, and the object does not know 
what name(s) is bound to it.


You could do this:

def swap(x_name, y_name):
g = globals()
g[x_name], g[y_name] = g[y_name], g[x_name]

which gives you something a little closer to c-b-r, but it still isn't 
the same thing. Some major differences:

- you can't affect values unless they are bound to a name, that is no 
swapping of anonymous values, e.g. swap(a[4], a[8]) could not work;

- within a nested scope, you can't affect anything unless it is in the 
global scope;

- you need to know the name to apply at runtime, there is no way to 
programmatically discover it. 

The third point is the most telling. Consider the Pascal procedure:

procedure swap(var x, var y: integer):
  var tmp: integer;
  begin
tmp := x;
x := y;
y := tmp;
  end;


Given two integer variables a and b, you call the procedure swap(a, b), 
and the compiler can determine what memory addresses are used. If Pascal 
was like Python, you would have to determine the addresses yourself:

a := 1;
b := 2;
swap(12693024, 190342874);

after which a would equal 2 and b would equal 1. Obviously Pascal is not 
like that, but Python is (using names instead of memory locations). This 
proves that Python names are nothing like Pascal call-by-reference 
arguments. Passing a name is *not* Python's way to emulate call-by-
reference.


-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-09 Thread greg

Steven D'Aprano wrote:

Not according to my Comp Sci lecturers back in the day, and not according 
to my Pascal books.


Pascal books will tell you what call-by-value means
in Pascal. You can't just blindly take that description
and apply it to other languages, just as you can't
take what your Pascal book says about assigment and
apply it blindly to Python without getting into
trouble.

Describing call-by-value as copying the value works
in Pascal, because assignment and copy are synonyms
in that language. But they're not synonyms in all
languages, so a language-independent definition of
call-by-value needs to describe it in a more general
way.

Refusing to accept that a more general definition
exists just because it's not mentioned in your Pascal
book is a little absurd.

--
Greg
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-09 Thread greg

Dennis Lee Bieber wrote:


You must have missed all the threads about binding then... Wherein
a Python assignment statement binds the LHS name to the RHS object
rather than assigns the RHS object value to the LHS


I know that it is sometimes referred to that way. But
nobody seems to get worked up into a religious fervour
and insist that the word assignment be banned from the
Python terminology lexicon, the way some people seem to
do about words such as value and reference.

If we can all get along nicely and accept that assignment
is an acceptable term, among alternatives, for something that
has an analogy, if not an exact equivalent, in other languages,
why can't we do the same for reference and call by value?

--
Greg
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-09 Thread Arnaud Delobelle
greg [EMAIL PROTECTED] writes:

 Arnaud Delobelle wrote:

 What's a variable reference?

 It's a reference to a variable. It's what gets passed behind
 the scenes when you use a VAR parameter in Pascal, or a
 ByRef parameter in VB.

Do you mean you can't do the following C++ snippet in Pascal or VB?  I
haven't used Pascal for more than 20 year and I have never used VB, so
this is a real question.

foo(int x) {
x = 7;
}

struct bar {
int i;
float j;
};

int main() {
int a[10];
bar b;
// What is passed to foo below is obviously not a 'variable
// reference' as the argument is not a variable.
foo(a[3]); // Now a[3] == 7
foo(b.i);  // Now b.i == 7
}

[...]

 Passing q by value means that the value of the expression 'q',
 whatever that is in the language concerned, gets assigned to the
 local variable 'p', whatever *that* means in the language concerned.

 Because of the way C assignment works, the result is that p ends
 up with a copy of the whole struct.

 Because of the way Python assignment works, the result is that
 p and q end up referring to the same object.

 The difference is *entirely* due to the difference in the semantics
 of assignment between the two languages. Once you've taken that
 into account, there is no need to look for difference in the
 parameter passing scheme.

I'm not sure that your definition of 'call by value' is widely
accepted.  If it was, then this thread wouldn't exist.

I've tried to google for an authoritative definition but it's harder
than I thought.  This definition comes up everywhere though.

call-by-value 

(CBV) An evaluation strategy where arguments are evaluated before
the function or procedure is entered. Only the values of the
arguments are passed and changes to the arguments within the called
procedure have no effect on the actual arguments as seen by the
caller.

[This from http://dictionary.reference.com/browse/call-by-value]

It seems to me that it more or less is the definition that most people
on this thread has been implicitly using.

-- 
Arnaud
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-09 Thread Marc 'BlackJack' Rintsch
On Sun, 09 Nov 2008 11:17:28 +, Arnaud Delobelle wrote:

 greg [EMAIL PROTECTED] writes:
 
 Arnaud Delobelle wrote:

 What's a variable reference?

 It's a reference to a variable. It's what gets passed behind the scenes
 when you use a VAR parameter in Pascal, or a ByRef parameter in VB.
 
 Do you mean you can't do the following C++ snippet in Pascal or VB?  I
 haven't used Pascal for more than 20 year and I have never used VB, so
 this is a real question.
 
 foo(int x) {
 x = 7;
 }
 
 struct bar {
 int i;
 float j;
 };
 
 int main() {
 int a[10];
 bar b;
 // What is passed to foo below is obviously not a 'variable
 // reference' as the argument is not a variable.
 foo(a[3]); // Now a[3] == 7
 foo(b.i);  // Now b.i == 7
 }

Translated to Pascal:

Program Test;

Type
Bar = Record
i: Integer;
j: Real;
End;

Var a: Array[0..9] Of Integer;
b: Bar;

Procedure Foo(Var x:Integer);
Begin
x := 7;
End;

Begin
Foo(a[3]);
WriteLn(a[3]); {Prints 7.}
Foo(b.i);
WriteLn(b.i);  {Prints 7.}
End.

In reality I would not expect that anything is passed here but that the 
compiler inlines it as direct assignment.  Should read: Copying the bit 
pattern of a 7 into the fixed memory locations.  :-)

Ciao,
Marc 'BlackJack' Rintsch
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-09 Thread greg

Arnaud Delobelle wrote:


What's a variable reference?


It's a reference to a variable. It's what gets passed behind
the scenes when you use a VAR parameter in Pascal, or a
ByRef parameter in VB.


What you're saying is that in the code below, when foo(q) is called
then 'p' in foo is another name for q in main. Right?

struct point {
int x;
int y;
}

int foo(point p) {
p.x = 42;
}

int main() {
point q = {0, 0};
foo(q);
/* So now you're saying that q.x == 0 ? */
}


No. Passing q by value means that the value of the expression 'q',
whatever that is in the language concerned, gets assigned to the
local variable 'p', whatever *that* means in the language concerned.

Because of the way C assignment works, the result is that p ends
up with a copy of the whole struct.

Because of the way Python assignment works, the result is that
p and q end up referring to the same object.

The difference is *entirely* due to the difference in the semantics
of assignment between the two languages. Once you've taken that
into account, there is no need to look for difference in the
parameter passing scheme.

--
Greg
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-09 Thread Terry Reedy

greg wrote:


No. Passing q by value means that the value of the expression 'q',
whatever that is in the language concerned, gets assigned to the
local variable 'p', whatever *that* means in the language concerned.


In other words, as I acknowledged in my other post, one can say that all 
calling is calling by value.


--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-09 Thread Terry Reedy

Joe Strout wrote:

On Nov 8, 2008, at 2:38 PM, Terry Reedy wrote:


So if you then insist that Python uses call by object,
you're actually saying it uses call by value!


Both Joe and you seem to be engaging in the following bit of sophistry:

In order for code A to call code B, some information must be 
communicated from A to B.  Something we all know ...


That information is a value of some sort. True...

Therefore all calling is calling by value.


Hey now, hang on.  That doesn't characterize my argument at all.  My 
argument is much simpler:


You can hardly get simpler than what I wrote.

--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-08 Thread Arnaud Delobelle
On Nov 8, 6:21 am, greg [EMAIL PROTECTED] wrote:
 Arnaud Delobelle wrote:
  'Pass by value' is not relevant to Python as variables do not contain
  anything.

 Where abouts in the phrase pass by value does the word
 contain appear?

You don't quote enough context for it to appear.
 You don't need a notion of containment in order for
 pass by value to have meaning. All you need is some
 notion of a value (it doesn't matter what) and
 some way to pass that value.

  'Pass by reference' is not relevant to Python as the language
  doesn't have the concept of object reference (in the sense of e.g. C++
  reference).

 What it doesn't have is the concept of a *variable*
 reference, which is what the reference in pass by
 reference means.

What's a variable reference?

  Here lies, IMHO, the reason why you think you need Python to 'pass by
  value'.  As you believe that variables must contain something, you think
  that assignment is about copying the content of a variable.  Assignment
  in Python is simply giving a new name to an object.

 Yes, and so is passing by value!

What you're saying is that in the code below, when foo(q) is called
then 'p' in foo is another name for q in main. Right?

struct point {
int x;
int y;
}

int foo(point p) {
p.x = 42;
}

int main() {
point q = {0, 0};
foo(q);
/* So now you're saying that q.x == 0 ? */
}

--
Arnaud

--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-08 Thread Joe Strout

On Nov 7, 2008, at 6:21 PM, Aaron Brady wrote:


Therefore objects don't need names to exist.  Having a name is
sufficient but not necessary to exist.  Being in a container is
neither necessary -nor- sufficient.


What do you mean?  Being in a container isn't necessary, but it  
certainly is sufficient.


Having ANY references to it is both necessary and sufficient to  
exist.  And isn't that the easiest way to say it?


Best,
- Joe

--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-08 Thread Aaron Brady
On Nov 8, 8:42 am, Joe Strout [EMAIL PROTECTED] wrote:
 On Nov 7, 2008, at 6:21 PM, Aaron Brady wrote:

  Therefore objects don't need names to exist.  Having a name is
  sufficient but not necessary to exist.  Being in a container is
  neither necessary -nor- sufficient.

 What do you mean?  Being in a container isn't necessary, but it  
 certainly is sufficient.

 Having ANY references to it is both necessary and sufficient to  
 exist.  And isn't that the easiest way to say it?

No, you forgot about cyclically-linked garbage, which Python
implementations are allowed to, but not required to, collect.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-08 Thread Aaron Brady
On Nov 8, 1:08 am, Steven D'Aprano [EMAIL PROTECTED]
cybersource.com.au wrote:
 On Sat, 08 Nov 2008 18:31:47 +1300, greg wrote:

Quote in favor of Steven snip

Example in favor of Steven snip

 There's no obviously about it. To anyone who has learned that call-by-
 value means that a copy is made, obviously it does mean copying the
 value. If you have learned a different meaning, then you will believe
 differently.

I don't think it's obvious to everyone what a copy constructor is and
when it's called.  That's ok, it's something you can learn.  I think
Joe's idea is that you can think of every variable in Python as a
pointer, and that clears up some confusions about its variable model.
What happens when a pointer is copied?  What is an example of copying
a pointer in spoken language?

 a= [ 1, 2, 3 ]

Are the following true?

The value of 'a' is an object.
The value of that object is [ 1, 2, 3 ].
The value of 'a' is [ 1, 2, 3 ].

If so, 'value' is ambiguous and therefore not very useful as a term.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-08 Thread Terry Reedy

greg wrote:

Joe Strout wrote:



Something has just occurred to me. If you take the
view that the value of an expression is an object,
then the terms value and object are synonymous.


Nope.  The result of an expression is an object with an id, class, and 
'value', where 'value' can include attributes (other than class) or 
non-attribute content or both.  The distinction does not matter much for 
immutables but it definitely does for mutable objects.



So if you then insist that Python uses call by object,
you're actually saying it uses call by value!


Both Joe and you seem to be engaging in the following bit of sophistry:

In order for code A to call code B, some information must be 
communicated from A to B.  Something we all know ...


That information is a value of some sort. True...

Therefore all calling is calling by value.

Well, yes, if you insist.  *But*, a distinction that does not 
distinguish is useless.  One might as well say Calling is calling.


In order to successfully program in Python, one must understand how 
functions are called.  That 'how' is distinct from the 'how' of some 
other languages.  Therefore, some of us claim, that 'how' should have a 
distinct name.


Terry Jan Reedy


--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-08 Thread Terry Reedy

Steven D'Aprano wrote:
In an attempt to keep this post from hitting the ridiculous length of one 


(Aside: I've learned one thing in this discussion. Despite the number of 
sources I've read that claim that if you pass an array to a C function 
the entire array will be copied, this does not appear to be true)


Since C does not have an array type, it is impossible to pass an array.
int *a, b[10] declares *both* a and b as int pointers.  As I remember, 
the only difference is that b is initialized to the address of an 
allocated block of 10.  In expressions, b is an int pointer, just like 
a, and a[i] and b[i] are defined the same, as *(a+i) and *(b+i), where 
the addition is pointer arithmetic. Function definitions can only define 
parameters as pointers (and lots else), not arrays.  So passing either a 
or b passes the address it represents.  (Function names also represent 
addresses in expressions, whereas, I believe, in C99 at least, struct 
names represent the struc, not its address.)


tjr

--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-08 Thread Aaron Brady
On Nov 8, 3:38 pm, Terry Reedy [EMAIL PROTECTED] wrote:
 In order for code A to call code B, some information must be
 communicated from A to B.  Something we all know ...

 That information is a value of some sort. True...

 Therefore all calling is calling by value.

 Well, yes, if you insist.  *But*, a distinction that does not
 distinguish is useless.  One might as well say Calling is calling.

Actually I like that.  We should call all call methods call by
calling, because it is a useful and consistent generalization.
--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-08 Thread Grant Edwards
On 2008-11-08, Terry Reedy [EMAIL PROTECTED] wrote:
 Steven D'Aprano wrote:
 In an attempt to keep this post from hitting the ridiculous length of one 

 (Aside: I've learned one thing in this discussion. Despite the number of 
 sources I've read that claim that if you pass an array to a C function 
 the entire array will be copied, this does not appear to be true)

 Since C does not have an array type, it is impossible to pass an array.
 int *a, b[10] declares *both* a and b as int pointers.  As I remember, 
 the only difference is that b is initialized to the address of an 
 allocated block of 10.

No, that's not true.  b is not a pointer that's initialized
with an address. b is a constant literal that is equivalent
to the address of the first element in the array.  IOW,
(void*)b == (void*)b == (void*)b[0].

That's not true for a.  (void*)a == (void*)a[0], 
but (void*)a != (void*)a.

 In expressions, b is an int pointer, just like a, and a[i] and
 b[i] are defined the same, as *(a+i) and *(b+i), where the
 addition is pointer arithmetic.

True, but a and b are very different, and a can be used as
an lvalue and b can not.  a is a variable, and b is a
literal constant (that can, for static storage classes, be
resolved to a value at compile/load time).

 Function definitions can only define parameters as pointers
 (and lots else), not arrays.  So passing either a or b passes
 the address it represents.  (Function names also represent 
 addresses in expressions, whereas, I believe, in C99 at least,
 struct names represent the struc, not its address.)

-- 
Grant

--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-08 Thread Joe Strout

On Nov 8, 2008, at 2:38 PM, Terry Reedy wrote:


So if you then insist that Python uses call by object,
you're actually saying it uses call by value!


Both Joe and you seem to be engaging in the following bit of  
sophistry:


In order for code A to call code B, some information must be  
communicated from A to B.  Something we all know ...


That information is a value of some sort. True...

Therefore all calling is calling by value.


Hey now, hang on.  That doesn't characterize my argument at all.  My  
argument is much simpler:


Python's call semantics are exactly the same as other modern OOP  
languages, where it is commonly called call-by-value (and it is, in  
fact, call-by-value, as you can see with the simple test of assigning  
to the formal parameter).  Therefore, we would reduce confusion if  
we'd get on board and call it that in Python, too.


Of course, I've softened my position somewhat, since being shown that  
call by sharing is simply a term for call-by-value in the case where  
the values are object references.  That clearly does apply to Python  
(as well as other OOP languages, where object references are  
involved), and as long as we can explain it as just a restricted form  
of call-by-value, I'm OK with that.


In order to successfully program in Python, one must understand how  
functions are called.  That 'how' is distinct from the 'how' of some  
other languages.


Which languages?  Certainly none of those at http://www.strout.net/info/coding/valref/ 
.  (Except that some of them have a by-reference option, which  
Python and Java do not.)


Best,
- Joe

--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-08 Thread Aaron Brady
On Nov 8, 10:59 pm, Joe Strout [EMAIL PROTECTED] wrote:
 Of course, I've softened my position somewhat, since being shown that  
 call by sharing is simply a term for call-by-value in the case where  
 the values are object references.  That clearly does apply to Python  
 (as well as other OOP languages, where object references are  
 involved), and as long as we can explain it as just a restricted form  
 of call-by-value, I'm OK with that.

Humor me briefly.  In 'x= [1, 2, 3]', do you think that the value of x
is a memory address?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-07 Thread Steven D'Aprano
On Fri, 07 Nov 2008 00:44:21 -0500, Steve Holden wrote:

 Steven D'Aprano wrote:
 On Thu, 06 Nov 2008 09:59:37 -0700, Joe Strout wrote:
 [...]
 And by definition, call by value means that the parameter is a copy.
 So if you pass a ten megabyte data structure to a function using
 call-by- value semantics, the entire ten megabyte structure is copied.
 
 Since this does not happen in Python, Python is not a call-by-value
 language. End of story.
 
 
 
 Without knowing that, you don't know what assignments to the formal
 parameter will do, or even what sort of arguments are valid. Answer:
 it's a copy of it.
 
 Lies, all lies. Python doesn't copy variables unless you explicitly ask
 for a copy. That some implementations of Python choose to copy pointers
 rather than move around arbitrarily large blocks of memory instead is
 an implementation detail. It's an optimization and irrelevant to the
 semantics of argument passing in Python.
 [...]
 
 Are you sure you meant to write this?

I'm not sure I understand what you're getting at. The only thing I can 
imagine is that you think there's some sort of contradiction between my 
two statements. I don't see why you think so. In principle one could 
create an implementation of Python with no stack at all, where everything 
lives in the heap, and all argument passing is via moving the actual 
objects (large blocks of memory) rather than references to the objects.

I don't mean to imply that this is a practical way to go about 
implementing Python, particularly given current computer hardware where 
registers are expensive and the call stack is ubiquitous. But there are 
other computing models, such as the register machine model which uses a 
hypothetically-infinite number of registers, no stack and no heap. With 
sufficient effort, one could implement a Python compiler using only a 
Turing Machine. Turing Machines don't have call-by-anything semantics. 
What would that say about Python?

Alternatively, you're commenting about my comment about copying pointers. 
I thought I had sufficiently distinguished between what takes place at 
the level of the Python VM (nothing is copied without an explicit request 
to copy it) and what takes place in the VM's implementation (the 
implementation is free to copy whatever pointers it wants as an 
optimization). If I failed to make that clear, I hope I have done so now.

Pointers do not exist at the level of the Python VM, but they clearly 
exist in the C implementation. We agree that C is call-by-value. CPython 
is (obviously) built on top of C's call-by-value semantics, by passing 
pointers (or references if you prefer) to objects. But that doesn't imply 
that Python's calling semantics are the same as C's.

Algol is call-by-name. Does anyone doubt that we could develop an Algol 
implementation of Python that used nothing but call-by-name semantics at 
the implementation level? Would that mean that Python was call-by-name?

The point is that Joe's argument is based on a confusion between the C 
implementation (calling a function with argument x makes a copy of a 
pointer to x and puts it into the stack for the function) and what 
happens at the level of the Python language.



-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-07 Thread Joe Strout

On Nov 6, 2008, at 10:35 PM, Steve Holden wrote:


That's good to hear. Your arguments are sometimes pretty good, and
usually well made, but there's been far too much insistence on all  
sides

about being right and not enough on reaching agreement about how
Python's well-defined semantics for assignment and function calling
should best be described.

In other words, it's a classic communication problem.


That's a fair point.  I'll try to do better.

I must say I find it strange when people try to contradict my  
assertion
that Python names are references to objects, when the (no pun  
intended)

reference implementation of the language uses reference counting to
track how many assignments have been made.


I agree.  It seems like we should be able to take that as a given.


So any argument that the language doesn't have the concept of object
reference (in the sense of e.g. C++ reference) is simply stating the
obvious: that Python has no way to declare reference variables. I  
would

argue myself that it has no need of such a mechanism precisely because
names are object references, and I'd like to hear counter-arguments.


Right.  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.  If I say  
name, an astute listener would reasonably say name of what -- and  
I don't want to have to say name of some thing in a name space which  
can be flexibly associated with an object when the simple term  
variable seems to work as well.



Well that's not true either. If I remember all the way back to my
computational science degree I seem to remember being taught that  
there
was call by *simple reference*, which is what I understand you to  
mean.

Suppose I write the following on some not-quite-Python language:

lst = ['one', 'two', 'three']

index = 1

def foo(item, i):
  i = 2
  item = ouch

foo(lst[index], index)
...
With call by simple reference, after the call I would expect the
following conditions to be true:

index == 2
lst == ['one', 'ouch', 'three']


Yes, I guess so, though it would require that lst[index] evaluate to  
an lvalue to which the 'item' parameter could be an alias.  (With the  
second parameter, 'i', the situation is more straightforward because  
you're passing in a simple variable rather than a more complex  
expression.)



With full call by reference, however, arguably the change to the value
of index would induce the post-conditions

index == 2
lst == ['one', 'two', 'ouch']

because the reference made by the first argument depends on the  
value of

a variable mutated inside the function call.


I confess that I've never heard of call by simple reference or call  
by full reference before.  What you're describing in the second case  
sounds more like call by name to me.


But I think we can agree that neither of these behaviors describes  
Python.


Why the resistance to these simple and basic terms that apply to  
any OOP

language?


Ideally I'd like to see this discussion concluded without resorting to
democratic appeals. Otherwise, after all, we should all eat shit:  
sixty

billion flies can't possibly be wrong.


I think I could make a good argument that the nutritional needs of  
flies are different from those of humans. On the other hand, 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?


What does give a new name to an object mean?  I submit that it  
means

exactly the same thing as assigns the name to refer to the object.


I normally internalize x = 3 as meaning store a reference to the
object 3 in the slot named x, and when I see x in an expression I
understand it to be a reference to some object, and that the value  
will

be used after dereferencing has taken place.


Works for me.


I've seen various descriptions of Python's name binding behavior in
terms of attaching Port-It notes bearing names to the objects  
reference

by the names, and I have never found them convincing. The reason for
this is that names live in namespaces, whereas values live in some  
other

universe altogether (that I normally describe as object space to
beginners, though this is not a term you will come across in the  
python

literature).


Agreed.  That model implies that all names are global, and completely  
fails to explain how one object might be named x and a 

Re: Finding the instance reference of an object

2008-11-07 Thread Steve Holden
Steven D'Aprano wrote:
 On Fri, 07 Nov 2008 00:44:21 -0500, Steve Holden wrote:
 
 Steven D'Aprano wrote:
 On Thu, 06 Nov 2008 09:59:37 -0700, Joe Strout wrote:
 [...]
 And by definition, call by value means that the parameter is a copy.
 So if you pass a ten megabyte data structure to a function using
 call-by- value semantics, the entire ten megabyte structure is copied.

 Since this does not happen in Python, Python is not a call-by-value
 language. End of story.



 Without knowing that, you don't know what assignments to the formal
 parameter will do, or even what sort of arguments are valid. Answer:
 it's a copy of it.
 Lies, all lies. Python doesn't copy variables unless you explicitly ask
 for a copy. That some implementations of Python choose to copy pointers
 rather than move around arbitrarily large blocks of memory instead is
 an implementation detail. It's an optimization and irrelevant to the
 semantics of argument passing in Python.
 [...]

 Are you sure you meant to write this?
 
 I'm not sure I understand what you're getting at. The only thing I can 
 imagine is that you think there's some sort of contradiction between my 
 two statements. I don't see why you think so. In principle one could 
 create an implementation of Python with no stack at all, where everything 
 lives in the heap, and all argument passing is via moving the actual 
 objects (large blocks of memory) rather than references to the objects.
 
 I don't mean to imply that this is a practical way to go about 
 implementing Python, particularly given current computer hardware where 
 registers are expensive and the call stack is ubiquitous. But there are 
 other computing models, such as the register machine model which uses a 
 hypothetically-infinite number of registers, no stack and no heap. With 
 sufficient effort, one could implement a Python compiler using only a 
 Turing Machine. Turing Machines don't have call-by-anything semantics. 
 What would that say about Python?
 
 Alternatively, you're commenting about my comment about copying pointers. 
 I thought I had sufficiently distinguished between what takes place at 
 the level of the Python VM (nothing is copied without an explicit request 
 to copy it) and what takes place in the VM's implementation (the 
 implementation is free to copy whatever pointers it wants as an 
 optimization). If I failed to make that clear, I hope I have done so now.
 
 Pointers do not exist at the level of the Python VM, but they clearly 
 exist in the C implementation. We agree that C is call-by-value. CPython 
 is (obviously) built on top of C's call-by-value semantics, by passing 
 pointers (or references if you prefer) to objects. But that doesn't imply 
 that Python's calling semantics are the same as C's.
 
 Algol is call-by-name. Does anyone doubt that we could develop an Algol 
 implementation of Python that used nothing but call-by-name semantics at 
 the implementation level? Would that mean that Python was call-by-name?
 
 The point is that Joe's argument is based on a confusion between the C 
 implementation (calling a function with argument x makes a copy of a 
 pointer to x and puts it into the stack for the function) and what 
 happens at the level of the Python language.
 
 
 
I am probably egregiously misunderstanding. The practical difficulty
with the moving huge blocks of data approach would appear to emerge
when a function that gets passed an instance of some container then
calls another function that references the same container as a global,
for example.

Again, I don't think we disagree about how Python actually works, but it
seemed to me that your statement obscured rather than helped.

regards
 Steve
-- 
Steve Holden+1 571 484 6266   +1 800 494 3119
Holden Web LLC  http://www.holdenweb.com/

--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-07 Thread Steven D'Aprano
On Thu, 06 Nov 2008 21:31:16 -0700, Joe Strout wrote:

 You're wrong, Python variables don't contain *anything*. Python
 variables are names in a namespace.
 
 I think we're saying the same thing.  What's a name?  It's a string of
 characters used to refer to something.  That which refers to something
 is a reference.

In some sense, I have to agree with that. Reference as a plain English 
word is very abstract.


 The thing it refers to is a referent.  I was trying to
 avoid saying the value of an object reference is a reference to an
 object since that seems tautological and you don't like my use of the
 word value, but I see you don't like contains either.

I'm happier with the idea that a name in Python refers to an object 
than your claim that variables contain a reference to an object. Let me 
explain:

In languages such as C and Pascal, a variable is a named memory location 
with an implied size. For the sake of the argument, let's assume 
variables are all two bytes in size, i.e. they can hold a single short 
integer. So, if the name 'x' refers to location 0x23A782, and the two 
bytes at that location are 0x0001, then we can legitimately say that the 
location 0x23A782 (otherwise known as 'x') _contains_ 1 because the byte 
pattern representing 1 is at that memory location.

But in Python, what you've been calling variables is explicitly a 
*mapping* between a name and a value. Unlike variables above, the 
compiler can't map a name to a memory location. At run time, the VM has 
to search a namespace for the name. If you disassemble Python byte-code, 
you will see things like:

LOAD_NAME 1 (x)

If you want to talk about something containing the value, that something 
would be the namespace, not the name: the name is the key in the hash 
table, and is a separate piece of data to the value. The key and the 
value are at different locations, you can't meaningfully say that the 
value is contained by the key, for the same reason that given a list 

[10, 11, 12, 13, 14, 15]

you wouldn't say that the int 12 was contained by the number 2.


 Maybe we can try something even wordier: a variable in Python is, by
 some means we're not specifying, associated with an object.  (This is
 what I mean when I say it refers to the object.)  Can we agree that
 far?

So far.


 Now, when you pass a variable into a method, the formal parameter gets
 associated with same object the actual parameter was associated with.

Agreed.


 I like to say that the object reference gets copied into the formal
 parameter, since that's a nice, simple, clear, and standard way of
 describing it.  I think you object to this way of saying it.  But are we
 at least in agreement that this is what happens?

At the implementation level of CPython, yes. In abstract, no. In 
abstract, we can't make *any* claims about what happens beyond the Python 
code, because we don't know how the VM is implemented. Perhaps it is a 
giant pattern in Conway's cellular automata Life, which is Turing 
Complete.

In practice, any reasonable implementation of Python on existing computer 
hardware is going to more-or-less do what the CPython implementation 
does. But just because every existing implementation does something 
doesn't mean it's not an implementation detail.

 
 But putting that aside, consider the Python code x = 1. Which
 statement would you agree with?

 (A) The value of x is 1.
 
 Only speaking loosely (which we can get away with because numbers are
 immutable types, as pointed out in the last section of [1]).

Why speaking loosely?

At the level of Python code, the object you have access to is nothing 
more or less than 1. There is a concrete representation of the abstract 
Platonic number ONE, and that concrete representation is written as 1.

The fact that the object 1 is immutable rather than mutable is 
irrelevant. After x = [] the value of x is the empty list.

As far as I am concerned, this is one place where the plain English 
definition of the word value is the only meaningful definition: what 
is denoted by a symbol. Or if you prefer, what the symbol represents. 
At the language level, x=1 means that x represents the object 1, nothing 
more and nothing less, regardless of how the mechanics of that 
representation are implemented.

The value of a variable is whatever thing you assign to that variable. If 
that thing is the int 1, then the value is the int 1. If the thing is a 
list, the value is that list. If the thing is a pointer, the value is a 
pointer. (Python doesn't give you access to pointers, but other languages 
do.) Whatever mechanism is used to implement that occurs at a deeper 
level. In Pascal and C, bytes are copied into memory locations (which is 
actually implemented by flipping bits at one location to match the state 
of bits at another location). In CPython and Java, pointers or references 
are created and pointed at complex data structures called objects. That's 
an implementation detail, just like flipping 

Re: Finding the instance reference of an object

2008-11-07 Thread Steven D'Aprano
On Fri, 07 Nov 2008 10:50:55 -0500, Steve Holden wrote:

 I am probably egregiously misunderstanding. The practical difficulty
 with the moving huge blocks of data approach would appear to emerge
 when a function that gets passed an instance of some container then
 calls another function that references the same container as a global,
 for example.

I have no doubt whatsoever that such an implementation would be fragile, 
complicated, convoluted and slow. In other words, it would be terrible. 
But that's merely a Quality of Implementation issue. It would still be 
Python.


-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-07 Thread Steve Holden
Steven D'Aprano wrote:
 On Fri, 07 Nov 2008 10:50:55 -0500, Steve Holden wrote:
 
 I am probably egregiously misunderstanding. The practical difficulty
 with the moving huge blocks of data approach would appear to emerge
 when a function that gets passed an instance of some container then
 calls another function that references the same container as a global,
 for example.
 
 I have no doubt whatsoever that such an implementation would be fragile, 
 complicated, convoluted and slow. In other words, it would be terrible. 
 But that's merely a Quality of Implementation issue. It would still be 
 Python.
 
 
OK, more specifically: I don't see how changes to the copy of the
(structure referenced by) the argument would be reflected in the global
structure. In other words, it seems to involve a change of semantics to
me, so I think I am misunderstanding you.

regards
 Steve
-- 
Steve Holden+1 571 484 6266   +1 800 494 3119
Holden Web LLC  http://www.holdenweb.com/

--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-07 Thread Steven D'Aprano
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 

Re: Finding the instance reference of an object

2008-11-07 Thread Steven D'Aprano
On Fri, 07 Nov 2008 11:37:28 -0500, Steve Holden wrote:

 Steven D'Aprano wrote:
 On Fri, 07 Nov 2008 10:50:55 -0500, Steve Holden wrote:
 
 I am probably egregiously misunderstanding. The practical difficulty
 with the moving huge blocks of data approach would appear to emerge
 when a function that gets passed an instance of some container then
 calls another function that references the same container as a global,
 for example.
 
 I have no doubt whatsoever that such an implementation would be
 fragile, complicated, convoluted and slow. In other words, it would be
 terrible. But that's merely a Quality of Implementation issue. It would
 still be Python.
 
 
 OK, more specifically: I don't see how changes to the copy of the
 (structure referenced by) the argument would be reflected in the global
 structure. In other words, it seems to involve a change of semantics to
 me, so I think I am misunderstanding you.

What, you want me to come up with an implementation? Okay, fine.

The VM keeps a list of the namespaces that contain such cloned objects. 
After each Python statement is executed, before the next one gets to run, 
the VM runs through that list and synchronizes each object in the 
caller's scope with the value of its clone in the function scope.



-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-07 Thread Marc 'BlackJack' Rintsch
On Fri, 07 Nov 2008 11:37:28 -0500, Steve Holden wrote:

 Steven D'Aprano wrote:
 On Fri, 07 Nov 2008 10:50:55 -0500, Steve Holden wrote:
 
 I am probably egregiously misunderstanding. The practical difficulty
 with the moving huge blocks of data approach would appear to emerge
 when a function that gets passed an instance of some container then
 calls another function that references the same container as a global,
 for example.
 
 I have no doubt whatsoever that such an implementation would be
 fragile, complicated, convoluted and slow. In other words, it would be
 terrible. But that's merely a Quality of Implementation issue. It would
 still be Python.
 
 
 OK, more specifically: I don't see how changes to the copy of the
 (structure referenced by) the argument would be reflected in the global
 structure. In other words, it seems to involve a change of semantics to
 me, so I think I am misunderstanding you.

Of course every copy has a list of references to other copies and time 
stamps associated with every attribute.  So when you access an attribute 
the implementation first chases all the links to the copies, and checks 
if the attribute has a newer time stamp there, so the value has to be 
copied back.  =:o)

More serious:  If you start to design distributed object oriented systems 
with call-by-sharing semantics you may end up with actually copying the 
value and propagating changes or checking for them in other copies.

Ciao,
Marc 'BlackJack' Rintsch
--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-07 Thread Joe Strout

On Nov 7, 2008, at 10:29 AM, Steven D'Aprano wrote:

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.


OK, that's a good point.  It strikes me as a generally Bad Idea to  
actually take advantage of that (i.e., to reassign to a class or  
module name), but I guess Python allows it.


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.


Right.  This may lead to the confusion that started this thread, i.e.  
someone asking how to find the name of an arbitrary object (by which  
they meant the entry in some namespace that refers to it, what I like  
to call a variable name).  If you think of objects as having names  
(which as you point out is sort of true in some cases but not in  
general), rather than names as referring to objects, then you get into  
this trouble.



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.


OK, so now we're getting down to it: you think that Python's behavior  
is like Java, but Java's behavior is different from C, right?


What would it take to convince you that Java and C have exactly the  
same semantics, and differ only in syntax?  Would equivalent code  
snippets that do the same thing do the job?



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?


Because you start with, say, integers, and make such observations as:

1. x = y copies the integer value from y into x.
2. foo(x), where foo's parameter is by-value, copies x into the formal  
parameter.
3. foo(x), where foo's parameter is by-reference (e.g. using  in C++,  
or using ByRef in RB/VB.NET), makes the formal parameter an alias of x.


Then you look at a declaration of (speaking loosely) object type, such  
as Java's


  SomeClass x;

or C++'s

  SomeClassPtr x;  // where typedef SomeClass* SomeClassPtr;

Then you ask, how do the above situations 1-3 apply to this?  Well,  
they apply just fine, except that what is being copied or aliased is  
the reference to an object rather than an integer.


That's the obvious generalization I was thinking of.

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


Strictly true, but irrelevant if float objects are immutable.   
Immutable objects can be treated as values; it's only by mutating an  
object that you can tell that you're dealing with references to shared  
data.


What dereferencing step? There's no such thing in Python code. You  
just

use the name, as normal.


If you just use the name, then you're accessing the reference.  To get  
to the actual data, you have to dereference it with ..  (Granted,  
this dereferencing is often done within operator methods so that it's  
mostly hidden from you in many cases, especially when dealing with  
number- and string-like objects.)


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's not what I'm talking about.  I'm talking about person.age in  
Python, Java, or .NET, or person-age in C/C++.



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


I've stated repeatedly that this is fine shorthand.  You only get into  
trouble when, instead of assigning 1, you are assigning (a reference  
to) some mutable object.  Then you have to think about whether you are  
copying the data or just copying a reference to it.


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.


Quite right.  We just disagree on what value means.  I think this is  
because Python is so restricted: everything is an 

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

2008-11-07 Thread Terry Reedy

Joe Strout wrote:

On Nov 6, 2008, at 10:35 PM, Steve Holden wrote:


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.


Python has two types of names.  Some complex objects -- modules, 
classes, and functions, and wrappers and subclasses thereof, have 
'definition names' that are used instead of a 'value' to print a 
representation.  Otherwise, names are identifiers, the term used in the 
grammar.


But I agree even two meaning is one too many.  Maybe 'label' would be a 
better short form for 'identifier'.  'Labeling' might be clearer for 
many beginners than 'name-binding'.


  Lots
of things have names that are not variables: modules have names, classes 
have names, methods have names, and so do variables.  If I say name, 
an astute listener would reasonably say name of what


Common nouns, when instantiated, become the name of whatever particular 
object they are associated with.


-- and I don't 
want to have to say name of some thing in a name space which can be 
flexibly associated with an object when the simple term variable 
seems to work as well.


'Variable' has many more meanings than 'name' or 'label' and overall 
seems to be more confusing, not less.  I say this as an empirical 
observation of c.l.p postings.  You yourself switched back and forth 
between two different meanings.


I'm with you there.  To me, the consistent simplicity is exactly this: 
all variables are object references, and these are always passed by value.


The me, this implies that the corresponding parameter should become a 
reference to that reference value.  In any case, the last 10 years of 
this newsgroups shows that describing Python calling as 'by value' 
confuses people so that they are surprised that mutating a list inside a 
function results in the list being mutated outside the function.


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, 


The Python Language Reference uses the word 'reference' but does not 
define it.  I take it to be 'whatever information an interpreter uses to 
associate a name or collection slot with an object and to retrieve the 
object (and possibly its value) when requested'.


Well of course.  I'm pretty sure I've said repeatedly that Python 
variables refer to objects on the heap.


Built-in objects are not allocated on the heap.


(Please replace heap with object space if you prefer.)


They are in abstract object space, although CPython occasionally leaks 
the abstraction in error messages about not being able to modify 
non-heap objects.


  I'm only saying that Python variables

don't contain any other type of value than references.


One problem with the word 'variable' is that variables are somethings 
thought of as 'containing', as you did above.  So you switch back and 
forth between 'variables *are* references' and 'variables *contain* 
references'.  Whereas a name (noun) definitely *is* a reference and not 
a container.


Ditto right back at you.  :)  So maybe here's the trouble: since all 
Python variables are references,


Back to *is*.

But continuing to attempt to gloss over that fact, when you come to 
parameter passing,


I believe most of us here try to follow Knuth's lead and use 'parameter' 
for the local names and 'argument' for the value/object that gets 
associated with the name.


not copied).  You also have to describe the assignment operator as 


In Python, assignment is not an operator by intentional design.

different from all other languages, since clearly that's not copying the 
object either.


Python's assignment *statement* does what we routinely do in everyday 
life when we assign new labels to things, whether permanently or 
temporarily.


 An assignment copies the RHS

reference into the LHS variable, nothing more or less.


Back to variable as container.
An assignment associates the RHS object(s) with the LHS target(s).

 A parameter  copies the argument reference into the formal parameter,

A function call associates objects derived from the argument expressions 
and stored defaults with the function parameters.



Isn't that simple, clear, and far easier to explain?


Applied to my version, I agree ;-).


I wonder if that could be tested systematically.  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.


Except for your garbling of the alternative to your version, I agree.
I suspect that different people might do better with different 
explanations, depending on background.


In my case, my understanding of Python became clear only once I stopped 
listening to all the confusing descriptions here, 

Re: Finding the instance reference of an object

2008-11-07 Thread Steve Holden
Steven D'Aprano wrote:
 On Fri, 07 Nov 2008 11:37:28 -0500, Steve Holden wrote:
 
 Steven D'Aprano wrote:
 On Fri, 07 Nov 2008 10:50:55 -0500, Steve Holden wrote:

 I am probably egregiously misunderstanding. The practical difficulty
 with the moving huge blocks of data approach would appear to emerge
 when a function that gets passed an instance of some container then
 calls another function that references the same container as a global,
 for example.
 I have no doubt whatsoever that such an implementation would be
 fragile, complicated, convoluted and slow. In other words, it would be
 terrible. But that's merely a Quality of Implementation issue. It would
 still be Python.


 OK, more specifically: I don't see how changes to the copy of the
 (structure referenced by) the argument would be reflected in the global
 structure. In other words, it seems to involve a change of semantics to
 me, so I think I am misunderstanding you.
 
 What, you want me to come up with an implementation? Okay, fine.
 
 The VM keeps a list of the namespaces that contain such cloned objects. 
 After each Python statement is executed, before the next one gets to run, 
 the VM runs through that list and synchronizes each object in the 
 caller's scope with the value of its clone in the function scope.
 
 
 
Right, so we replace references to values with references to namespaces?

Anyway, thanks. I'm really glad you stated up-front that this was not a
practical execution scheme.

regards
 Steve
-- 
Steve Holden+1 571 484 6266   +1 800 494 3119
Holden Web LLC  http://www.holdenweb.com/

--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-07 Thread Terry Reedy

Steven D'Aprano wrote:

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


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.


3.0 corrects that divergence.
 def foo(): pass

 foo.__name__
'foo'

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


-
http://en.wikipedia.org/wiki/Call_by_something#Call_by_sharing

Call by sharing

Also known as call by object or call by object-sharing is an 
evaluation strategy first named by Barbara Liskov et al for the language 
CLU in 1974[1]. It is used by languages such as Python[2] and Iota and 
(as argued by some[3]) Java, although the term is not in common use by 
the Java community. Call-by-sharing implies that values in the language 
are based on objects rather than primitive types.


The semantics of call-by-sharing differ from call-by-reference in that 
assignments to function arguments within the function aren't visible to 
the caller (unlike by-reference sematics). However since the function 
has access to the same object as the caller (no copy is made), mutations 
to those objects within the function are visible to the caller, which 
differs from call-by-value semantics.


Although this term has widespread usage in the Python community, 
identical semantics in other languages such as Java and Visual Basic are 
often described as call-by-value, where the value is implied to be a 
reference to the object.


-
http://www.pmg.csail.mit.edu/papers/thetaref/node34.html

Call by Sharing
The caller and called routine communicate only through the argument and 
result objects; routines do not have access to any variables of the caller.


After the assignments of actual arguments to formal arguments, the 
caller and the called routine share objects. If the called routine 
modifies a shared object, the modification is visible to the caller on 
return. The names used to denote the shared objects are distinct in the 
caller and called routine; if a routine assigns an object to a formal 
argument variable, there is no effect on the caller. From the point of 
view of the invoked routine, the only difference between its formal 
argument variables and its other local variables is that the formals are 
initialized by its caller.


==
Python object *do* have access to surrounding scopes, but the second 
paragraph exact described Python, as does the corresponding Wikipedia entry.

==
myweb.lmu.edu/dondi/fall2004/cmsi585/subroutines-in-depth.pdf

• Call by sharing
– Used by languages where variables are already references to objects
– Parameters are references to objects, but assignments to those parameters
don’t change them at the level of the caller — e.g. Java uses call-by-value
for primitives (int, char) and uses call-by-sharing for Objects
---

And Google had other links to course notes using 'call by sharing'

Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-07 Thread Joe Strout

On Nov 7, 2008, at 12:13 PM, Terry Reedy wrote:

Python has two types of names.  Some complex objects -- modules,  
classes, and functions, and wrappers and subclasses thereof, have  
'definition names' that are used instead of a 'value' to print a  
representation.  Otherwise, names are identifiers, the term used in  
the grammar.


But I agree even two meaning is one too many.  Maybe 'label' would  
be a better short form for 'identifier'.  'Labeling' might be  
clearer for many beginners than 'name-binding'.


I actually rather like identifier, though it seems a little too  
technical for casual use.  On the other hand, label seems too  
arbitrary -- variable is a common term, and accurate enough to me.


'Variable' has many more meanings than 'name' or 'label' and overall  
seems to be more confusing, not less.  I say this as an empirical  
observation of c.l.p postings.  You yourself switched back and forth  
between two different meanings.


Did I?  What were they?  I thought I had a clear idea what I mean by  
it (and, as far as I know, it's consistent with what everybody else  
means by it too).  The only oddity in Python is that things you might  
not expect to be variables (such as module names) actually are.  But  
that's a succinct way to express that observation; saying module  
names are variables too seems to imply all the right things (e.g.  
that you can assign new values to them, or assign them to other  
variables).


I'm with you there.  To me, the consistent simplicity is exactly  
this: all variables are object references, and these are always  
passed by value.


To me, this implies that the corresponding parameter should become a  
reference to that reference value.


Really?  You've just described passing an object reference by  
reference.  If passing a reference by value implies adding an  
additional reference to it, then what would passing a reference by  
reference mean to you? And, examining your thought process, can you  
explain where that implication came from?


 In any case, the last 10 years of this newsgroups shows that  
describing Python calling as 'by value' confuses people so that they  
are surprised that mutating a list inside a function results in the  
list being mutated outside the function.


Yes, but that would happen ONLY when they also think that a variable  
actually contains the object data.  And since there are many here  
trying to claim exactly that, I think that is the root cause of the  
problem, not calling parameter passing by value.


And this belief (that the value of a variable is an object) leads to  
other mistaken beliefs too, such as that assignment should make a copy:


  x = y
  x.foo = bar

Anyone surprised by the list mutation inside a function should also be  
surprised to find that y.foo = bar.  I think we should simply address  
the root cause of that confusion, not try to redefine their  
understanding of how parameters are passed, and ALSO redefine what  
assignment means.


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,


The Python Language Reference uses the word 'reference' but does not  
define it.  I take it to be 'whatever information an interpreter  
uses to associate a name or collection slot with an object and to  
retrieve the object (and possibly its value) when requested'.


Sure, that's fine.  It doesn't really matter how it's implemented.   
What matters is that a name or collection slot somehow refers to an  
object, and whatever the form of that reference is, it is copied (*)  
to the LHS of an assignment or to the formal parameter of a function  
call.


(*) I was going to say transferred but when something is transferred  
from A to B, it implies that B gains it and A loses it.  Copied has  
the right implication: that afterwards, both A and B now have it.



  I'm only saying that Python variables

don't contain any other type of value than references.


One problem with the word 'variable' is that variables are  
somethings thought of as 'containing', as you did above.  So you  
switch back and forth between 'variables *are* references' and  
'variables *contain* references'.


Perhaps this is the two meanings you mentioned above.  I'm not sure I  
see any useful dichotomy here, though.  In C, we say that this  
variable is an integer, that variable is a character, the one over  
there is a double.  This is unambiguous shorthand for the declared  
type of this variable is such-and-so, and each such variable contains  
data of that type.  So there's no harm in saying that a variable is an  
integer, or that a variable contains an integer, as the context  
requires.


In Python, AFAICT, there is only one type, the object reference.  So,  
the type of every variable is 'reference', and each one contains a  
reference.


 Whereas a name (noun) definitely *is* a reference and not a  
container.


Yes, I'll grant 

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

2008-11-07 Thread Joe Strout

On Nov 7, 2008, at 12:35 PM, Terry Reedy wrote:


http://en.wikipedia.org/wiki/Call_by_something#Call_by_sharing

Call by sharing

Also known as call by object or call by object-sharing is an  
evaluation strategy first named by Barbara Liskov et al for the  
language CLU in 1974[1]. It is used by languages such as Python[2]  
and Iota and (as argued by some[3]) Java, although the term is not  
in common use by the Java community. Call-by-sharing implies that  
values in the language are based on objects rather than primitive  
types.


The semantics of call-by-sharing differ from call-by-reference in  
that assignments to function arguments within the function aren't  
visible to the caller (unlike by-reference sematics). However since  
the function has access to the same object as the caller (no copy is  
made), mutations to those objects within the function are visible to  
the caller, which differs from call-by-value semantics.


Although this term has widespread usage in the Python community,  
identical semantics in other languages such as Java and Visual Basic  
are often described as call-by-value, where the value is implied to  
be a reference to the object.


You know, people rip on Wikipedia, but I'm often surprised at how  
frequently it succinctly and accurately describes a topic, even when  
it is a topic of much controversy.  The above summary seems spot on.   
My difficulty, I guess, is that I'm coming from the Java/VB/RB  
community, where the semantics are exactly the same as Python, and  
where it makes perfect sense to call it call-by-value (since it is a  
trivial generalization of the very same evaluation strategy used on  
other types).  But I get here, and there is widespread use of this  
call-by-sharing term (though my initial impressions were much more  
disparate and confusing than the above concise summary makes it sound).


Thanks for pointing this out.  I'd only found the entry on evaluation  
strategies, which makes no mention of call-by-sharing.



http://www.pmg.csail.mit.edu/papers/thetaref/node34.html

Call by Sharing
The caller and called routine communicate only through the argument  
and result objects; routines do not have access to any variables of  
the caller.


After the assignments of actual arguments to formal arguments, the  
caller and the called routine share objects. If the called routine  
modifies a shared object, the modification is visible to the caller  
on return. The names used to denote the shared objects are distinct  
in the caller and called routine; if a routine assigns an object to  
a formal argument variable, there is no effect on the caller. From  
the point of view of the invoked routine, the only difference  
between its formal argument variables and its other local variables  
is that the formals are initialized by its caller.


==
Python object *do* have access to surrounding scopes, but the second  
paragraph exact described Python, as does the corresponding  
Wikipedia entry.


Well yes, but it exactly describes VB.NET, RB, Java, and C++ as well  
(when talking about object types rather than primitive types).



==
myweb.lmu.edu/dondi/fall2004/cmsi585/subroutines-in-depth.pdf

• Call by sharing
– Used by languages where variables are already references to objects
– Parameters are references to objects, but assignments to those  
parameters
don’t change them at the level of the caller — e.g. Java uses call- 
by-value

for primitives (int, char) and uses call-by-sharing for Objects


Well, not according to the Java specification, it doesn't.  But these  
sources finally make it clear that call-by-sharing is just a special  
case of call-by-value when the value is an object reference.  So, it's  
accurate to say that Java (and all the other languages under  
discussion) always use call-by-value, but some of those calls  
(depending on the parameter data type) may also be described as call- 
by-sharing.


I suppose it's reasonable that if you use a language where some types  
are references and some types are not, the simplest thing is to  
describe all calls as call-by-value (except for those with an optional  
by-reference syntax, like C++ and RB/.NET).  But if you come from a  
language where all types are references, then it's reasonable to  
describe all calls as call-by-sharing (provided the language doesn't  
also support call-by-reference).


So.  How about this for a summary?

Python uses call-by-sharing.  That's a special case of call-by-value  
where the variables are references to objects; it is these references  
that are copied to the parameters, not the objects themselves.  For  
users of other languages, this is the same semantics used for objects  
in Java, RB/VB.NET, and C++ when dealing with objects.


Best,
- Joe

--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-07 Thread Arnaud Delobelle
Joe Strout [EMAIL PROTECTED] writes:

 So.  How about this for a summary?

 Python uses call-by-sharing.  That's a special case of call-by-value
 where the variables are references to objects; it is these references
 that are copied to the parameters, not the objects themselves.  For
 users of other languages, this is the same semantics used for objects
 in Java, RB/VB.NET, and C++ when dealing with objects.

Here's a story about call by sharing:

One day a black cat came strolling into our garden.  It seemed quite
hungry so we gave it some milk and food remains.  The cat drank the milk
and ate the food, stayed for a bit then walked away.  A couple of days
later it came back, miaowing, so we fed it again.  It started coming to
see us almost every day, sometimes sleeping in the house, sometimes
disappearing for a day or two.  We started thinking of it as our cat and
we *named* it Napoleon.  Napoleon became very popular and stayed at home
more and more often, and very young son was very fond of it, calling it
something like 'Polion'.

Unfortunately Napoleon got infested with fleas and we had to take him to
the vet.  The vet scanned Napoleon with a little machine and discovered
that it had an ID chip.  This revealed that Napoleon was really called
Nelson (ironically!) and belonged to a house down our road.  We
contacted them and they were happy to 'share' the cat with us.  By this
time the cat answered to the name of Napoleon so we carried on calling
it this name.

This story ends quite sadly.  One day Napoleon escaped out the front
door and got run over by a passing van.  Our son kept asking for Polion
so we decided to get a new cat and called him Napoleon as well (we
decided it would be easier for him!).

Now some questions about the story:

1. Is Napoleon a copy of Dobby or are they the same cat?

2. Is Polion a copy of Napoleon or are they the same cat?

3. When we got rid of Napoleon's fleas, was Nelson deflea-ed as well?

4. When Napoleon died, did Nelson die as well?

5. When we got a new Napoleon, does this mean that our neighbours got a
   new Nelson?

Now a question about the questions about the story:

   To be able to understand the story and answer questions 1-5, do we
   need to think of Napoleon, Nelson and Polion as variables containing
   references to cat objects, or is it enough to think of them as three
   names for cats?

-- 
Arnaud
--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-07 Thread Steve Holden
Joe Strout wrote:
 On Nov 7, 2008, at 12:13 PM, Terry Reedy wrote:
[...]
 I wonder if that could be tested systematically.  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.

 Except for your garbling of the alternative to your version, I agree.
 I suspect that different people might do better with different
 explanations, depending on background.
 
 Could be.
 
 Maybe we could run such an experiment at PyCon, pulling in non-attendees
 from the hallway and getting them to take the test in exchange for a
 free donut or coffee.
 
+1: great idea! It would make a good video too ...

regards
 Steve
-- 
Steve Holden+1 571 484 6266   +1 800 494 3119
Holden Web LLC  http://www.holdenweb.com/

--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-07 Thread Aaron Brady
On Nov 7, 3:03 pm, Arnaud Delobelle [EMAIL PROTECTED] wrote:
 Joe Strout [EMAIL PROTECTED] writes:
  So.  How about this for a summary?

  Python uses call-by-sharing.  That's a special case of call-by-value
  where the variables are references to objects; it is these references
  that are copied to the parameters, not the objects themselves.  For
  users of other languages, this is the same semantics used for objects
  in Java, RB/VB.NET, and C++ when dealing with objects.

 Here's a story about call by sharing:

 One day a black cat came strolling into our garden.  It seemed quite
 hungry so we gave it some milk and food remains.  The cat drank the milk
 and ate the food, stayed for a bit then walked away.  A couple of days
 later it came back, miaowing, so we fed it again.  It started coming to
 see us almost every day, sometimes sleeping in the house, sometimes
 disappearing for a day or two.  We started thinking of it as our cat and
 we *named* it Napoleon.  Napoleon became very popular and stayed at home
 more and more often, and very young son was very fond of it, calling it
 something like 'Polion'.

 Unfortunately Napoleon got infested with fleas and we had to take him to
 the vet.  The vet scanned Napoleon with a little machine and discovered
 that it had an ID chip.  This revealed that Napoleon was really called
 Nelson (ironically!) and belonged to a house down our road.  We
 contacted them and they were happy to 'share' the cat with us.  By this
 time the cat answered to the name of Napoleon so we carried on calling
 it this name.

 This story ends quite sadly.  One day Napoleon escaped out the front
 door and got run over by a passing van.  Our son kept asking for Polion
 so we decided to get a new cat and called him Napoleon as well (we
 decided it would be easier for him!).

 Now some questions about the story:
Sorry didn't read above yet.

 1. Is Napoleon a copy of Dobby or are they the same cat?
Same cat.

 2. Is Polion a copy of Napoleon or are they the same cat?
Same cat.

 3. When we got rid of Napoleon's fleas, was Nelson deflea-ed as well?
Yes.

 4. When Napoleon died, did Nelson die as well?
No, honey.  He lives on in all of us.

 5. When we got a new Napoleon, does this mean that our neighbours got a
    new Nelson?
No, darling, Nelson is just sleeping.  When we got a New Orleans,
where did the old one go?

 Now a question about the questions about the story:

    To be able to understand the story and answer questions 1-5, do we
    need to think of Napoleon, Nelson and Polion as variables containing
    references to cat objects, or is it enough to think of them as three
    names for cats?

I think they are names, implying that Python has a different variable
model than C++.

However, a[0] isn't exactly a name, per se, and if you say that 'b'
and 'a[0]' are names of an object, then 'a[1-1]', 'a[2*0]', etc. are
all names of it.  Furthermore, some class models variables like this:

a.b= 'abc'
a.c= 'def'
a.d= 'ghi'

It also allows index access: a[0], a[1], a[2], respectively.  'abc'
has two names: 'a.b', and 'a[0]'.  Correct?

--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-07 Thread Arnaud Delobelle
Aaron Brady [EMAIL PROTECTED] writes:

  Furthermore, some class models variables like this:

 a.b= 'abc'
 a.c= 'def'
 a.d= 'ghi'

 It also allows index access: a[0], a[1], a[2], respectively.  'abc'
 has two names: 'a.b', and 'a[0]'.  Correct?

You know very well that a.b and a[0] aren't names, they are function
calls written in short hand ;)

a.b   is   getattr(a, 'b')
a[0]  is   getattr(a, '__getitem__')(0)

So they just return an object, which happens to be the same :)

-- 
Arnaud
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-07 Thread Douglas Alan
Joe Strout [EMAIL PROTECTED] writes:

 As for where I get my definitions from, I draw from several sources:

 1. Dead-tree textbooks

You've been reading the wrong textbooks.  Read Liskov -- she's called
CLU (and hence Python's) calling strategy call-by-sharing since the
70s.

 2. Wikipedia [2] (and yes, I know that has to be taken with a grain of
 salt, but it's so darned convenient)
 3. My wife, who is a computer science professor and does compiler
 research
 4. http://javadude.com/articles/passbyvalue.htm (a brief but excellent
 article)
 5. Observations of the ByVal (default) mode in RB and VB.NET
 6. My own experience implementing the RB compiler (not that
 implementation details matter, but it forced me to think very
 carefully about references and parameter passing for a very long time)

 Not that I'm trying to argue from authority; I'm trying to argue from
 logic.  I suspect, though, that your last comment gets to the crux of
 the matter, and reinforces my guess above: you don't think c-b-v means
 what most people think it means.  Indeed, you don't think any of the
 languages shown at [1] are, in fact, c-b-v languages.  If so, then we
 should focus on that and see if we can find a definitive answer.

I'll give you the definitive answer from a position of authority,
then.  I took Barbara Liskov's graduate-level class in programming
language theory at MIT, and she called what Python does
call-by-sharing.

|oug
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-07 Thread Douglas Alan
Joe Strout [EMAIL PROTECTED] writes:

 Yes, OK, that's great.  But there are several standard pass-by-
 somethings that are defined by the CS community, and which are simple
 and clear and apply to a wide variety of languages.  Pass by object
 isn't one of them.

Call-by-sharing *is* one of them, and the term has been around since
the 70s:

   http://hopl.murdoch.edu.au/showlanguage.prx?exp=637

 I guess if you want to campaign for it as a shorthand for object
 reference passed by value, you could do that, and it's not
 outrageous.

There's no need for a campaign.  The term has already been used in the
academic literature for 34 years.

 But to anybody new to the term, you should explain it as exactly
 that, rather than try to claim that Python is somehow different from
 other OOP languages where everybody calls it simply pass by value.

It's not true that everybody calls it simply pass by value.

 OK, if there were such a thing as pass-by-object in the standard
 lexicon of evaluation strategies, I would be perfectly happy saying
 that a system has it if it behaves as though it has it, regardless of
 the underpinnings.

There is call-by-sharing in the standard lexicon of evaluation
strategies, and it's been in the lexicon since 1974.

 However, if you really think the term is that handy, and we want to
 agree to say Python uses pass by object and answer the inevitable
 huh? question with that's shorthand for object references passed by
 value, then I'd be OK with that.

Excellent.  We can all agree to get along then!

|oug
--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-07 Thread Aaron Brady
On Nov 7, 3:39 pm, Arnaud Delobelle [EMAIL PROTECTED] wrote:
 Aaron Brady [EMAIL PROTECTED] writes:
   Furthermore, some class models variables like this:

  a.b= 'abc'
  a.c= 'def'
  a.d= 'ghi'

  It also allows index access: a[0], a[1], a[2], respectively.  'abc'
  has two names: 'a.b', and 'a[0]'.  Correct?

 You know very well that a.b and a[0] aren't names, they are function
 calls written in short hand ;)

 a.b   is   getattr(a, 'b')
 a[0]  is   getattr(a, '__getitem__')(0)

 So they just return an object, which happens to be the same :)

 --
 Arnaud

Therefore objects don't need names to exist.  Having a name is
sufficient but not necessary to exist.  Being in a container is
neither necessary -nor- sufficient.

a is the name of an object.  The object is associated with a
dictionary you can usually access.  'b' is a key in the dictionary.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-07 Thread greg

Steven D'Aprano wrote:
Python's behaviour is not the same as what 
Pascal, or C, calls call-by-value.


Python's assignment is not the same as what Pascal or C calls
assignment, either. Yet we don't hear anyone claim that the
term assignment shouldn't be used in Python.

The difference between call-by-value in Python and Pascal is
exactly the same difference as there is between assignment
in Python and Pascal. Why should we throw out one term but
not the other?

--
Greg
--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-07 Thread Steven D'Aprano
In an attempt to keep this post from hitting the ridiculous length of one 
of my posts last night, I'm going to skip over a lot of things Joe writes 
that aren't critical. Just because I've skipped over a comment doesn't 
mean I agree with it, merely that I don't think it gains much to argue 
the point.


On Fri, 07 Nov 2008 11:55:21 -0700, Joe Strout wrote:

 What would it take to convince you that Java and C have exactly the same
 semantics, and differ only in syntax?  Would equivalent code snippets
 that do the same thing do the job?

Of course not. You would also have to demonstrate that there is nothing 
you can do in C that can't be done directly in Java, and vice versa.

I say directly, because once you allow indirect techniques, you can do 
all sorts of things. Here's an indirect proof that Python is call-by-
reference:

def swap(x, y):
Swap the values referred to by x and y.
x[0], y[0] = y[0], x[0]

x = [2]
y = [3]
swap(x, y)
assert x == [3] and y == [2]

See, Python is call-by-reference!!! Not.

Here's a short C snippet:

#include stdio.h
#include stdlib.h

struct record
{
  int x;
  int y;
  int z;
};

void mutate(struct record p)
{
  p.x = 0;
  printf(Inside: %d %d %d\n, p.x, p.y, p.z);
}

struct record A;

int main(void)
{
  A.x = 1; A.y = 1; A.z = 1;
  printf(Outside: %d %d %d\n, A.x, A.y, A.z);
  mutate(A);
  printf(Outside: %d %d %d\n, A.x, A.y, A.z);
  return 0;
}


It prints:

Outside: 1 1 1
Inside: 0 1 1
Outside: 1 1 1


Note that mutations to the struct inside the function aren't visible 
outside the function. This is typical call-by-value behaviour: the 
argument is copied. How do you get this behaviour in Java without relying 
on tricks and indirect techniques as in the Python code above?

(Aside: I've learned one thing in this discussion. Despite the number of 
sources I've read that claim that if you pass an array to a C function 
the entire array will be copied, this does not appear to be true. Perhaps 
C is more like Java than I thought. Or perhaps my C coding skills are 
even more pathetic than I thought.)


[...]
  Personally, they would have to be pretty big to make me give up saying
  that the value of x after x=1 is 1.
 
 I've stated repeatedly that this is fine shorthand.  You only get into  
 trouble when, instead of assigning 1, you are assigning (a reference  
 to) some mutable object.  Then you have to think about whether you are  
 copying the data or just copying a reference to it.

Please explain the nature of this trouble that you describe, 
specifically in the context of Python.

If you understand the Python model (call-by-sharing, assignment is 
binding to names and not an operation on objects) then there is no such 
trouble *unless* you insist on interpreting things otherwise. You have a 
choice: give up the commonsense meaning of the word value merely to 
allow you to claim Python is call-by-value (where value is a pointer to 
the value you care about). Or you can keep the commonsense definition of 
value (that which a symbol represents) and stop claiming that Python is 
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
 
 I'm not changing the definition of value, I'm merely being precise  
 about it.

And yet you keep needing to say where the value is a reference. The 
fact that you need to do this proves that what you are doing is 
surprising to people.

If I want somebody to put a book on top of a box sitting on a table, I 
don't feel the need to say Put the book on top of the box, where the top 
is the part of the box pointing towards the sky. That's understood, from 
the ordinary meaning of the word. But you say Put the book on top of the 
box, where the top is the part of the box in contact with the table., 
and then argue black and blue that for primitive boxes, the top points to 
the sky but for all the other boxes, the top points to the ground. You 
only need to give that explanation because you're changing the definition.

When I execute x=1 and then say the value of x is 1, I don't need to 
explain what I mean by value because I'm using the general meaning of 
the word: that which a symbol represents. In Python code, the symbol x 
represents the object 1. It doesn't matter whether 1 is a primitive or an 
object, or whether 1 is mutable or immutable.

But you insist on an extra layer of indirection, because you want to talk 
about an implementation detail and give value a non-standard meaning: 
value, to you, is a reference to the thing which the symbol represents. 
But only for certain things. For other things, the value is the thing 
itself.

This isn't precision, it's obfuscation, partly because it complicates the 
meaning of value, but more importantly because you're not talking at 
the relevant level any more. You're not discussing the Python object 
model, or the behaviour of Python code, you're discussing one specific 

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

2008-11-07 Thread Steven D'Aprano
On Fri, 07 Nov 2008 13:05:16 -0700, Joe Strout wrote:

 In Python, AFAICT, there is only one type, the object reference.  So,
 the type of every variable is 'reference', and each one contains a
 reference.

This is wrong. If we take variable to mean name, then Python names do 
not have types. But *objects* have types, and there are many of them:

 a = 23; type(a)
type 'int'
 a = foo; type(a)
type 'str'
 a = []; type(a)
type 'list'

But a name that isn't bound to an object doesn't have a type:

 del a; type(a)
Traceback (most recent call last):
  File stdin, line 1, in module
NameError: name 'a' is not defined

The type information is associated with the object, not with the name.

It is possible that, in the C implementation, there is a C-type 
'reference' and all(?) C variables relating to the implementation of 
namespaces have that type. Possibly. But even if true, that's the wrong 
level of description.


-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-07 Thread Steven D'Aprano
On Sat, 08 Nov 2008 17:12:00 +1300, greg wrote:

 Steven D'Aprano wrote:
 Python's behaviour is not the same as what Pascal, or C, calls
 call-by-value.
 
 Python's assignment is not the same as what Pascal or C calls
 assignment, either. Yet we don't hear anyone claim that the term
 assignment shouldn't be used in Python.

Er, you're not from around here are you?

I admit that sometimes I slip into bad habits, but generally the accepted 
terminology is that x = 1 binds the object 1 to the name x.


 The difference between call-by-value in Python and Pascal is exactly the
 same difference as there is between assignment in Python and Pascal. Why
 should we throw out one term but not the other?

Exactly.



-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-07 Thread greg

Marc 'BlackJack' Rintsch wrote:


You have said the value that is copied is a pointer to the object.


This assumes that call by value means call by copying
the value.

That assumption is WRONG.

It doesn't mean that. It means call by ASSIGNING the
value.

So, you can think of the value of an expression as being
an object, as opposed to a reference to an object, if
you want. But then you need to consider what it means
to assign that value to a name.

Obviously it doesn't mean copying the value -- it must
mean making the name refer to the value somehow.

The same thing happens when the value is passed to a
function.

--
Greg
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-07 Thread greg

Arnaud Delobelle wrote:


'Pass by value' is not relevant to Python as variables do not contain
anything.


Where abouts in the phrase pass by value does the word
contain appear?

You don't need a notion of containment in order for
pass by value to have meaning. All you need is some
notion of a value (it doesn't matter what) and
some way to pass that value.


'Pass by reference' is not relevant to Python as the language
doesn't have the concept of object reference (in the sense of e.g. C++
reference).


What it doesn't have is the concept of a *variable*
reference, which is what the reference in pass by
reference means.


Here lies, IMHO, the reason why you think you need Python to 'pass by
value'.  As you believe that variables must contain something, you think
that assignment is about copying the content of a variable.  Assignment
in Python is simply giving a new name to an object.


Yes, and so is passing by value!

--
Greg
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-07 Thread greg

Joe Strout wrote:

On Nov 5, 2008, at 2:06 PM, Lie wrote:


Another example: pass-by-object.


Here's where we depart, I guess.  I think there's no such thing (see 
http://en.wikipedia.org/wiki/Evaluation_strategy  for example, and the 
dead-tree references I have on hand agree).


Something has just occurred to me. If you take the
view that the value of an expression is an object,
then the terms value and object are synonymous.

So if you then insist that Python uses call by object,
you're actually saying it uses call by value!

--
Greg
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-07 Thread Steven D'Aprano
On Sat, 08 Nov 2008 18:31:47 +1300, greg wrote:

 Marc 'BlackJack' Rintsch wrote:
 
 You have said the value that is copied is a pointer to the object.
 
 This assumes that call by value means call by copying the value.
 
 That assumption is WRONG.

Not according to my Comp Sci lecturers back in the day, and not according 
to my Pascal books.

E.g. Programming In Pascal, 2nd Edition (1985), by Peter Grogono of 
Concordia University refers to value parameters and variable 
parameters to refer to the standard Pascal call-by-value convention and 
the call-by-reference convention you get when you declare a parameter 
with the var keyword. He writes:

When an object is passed to a procedure by value, a local copy of it is 
made. If the object is a large array, the copying operation will make the 
program slower and will increase its memory requirements.

This was written as an undergraduate textbook. Remember that in 1985, OOP 
was far more exotic than now, and object in the above means any Pascal 
type (integer, array, set etc.) and not object as we understand it today.

Grogono doesn't explicitly use the terms call-by-value and call-by-
reference, but my lecture notes from the time make it clear that the 
Melbourne University Comp Sci department understood those terms to imply 
Pascal calling semantics.


 It doesn't mean that. It means call by ASSIGNING the value.

Which, in languages like Pascal, means COPYING the value. And that leads 
to confusion when people who understand C-B-V to mean what Pascal means 
by the term hear that Python is C-B-V.


 So, you can think of the value of an expression as being an object, as
 opposed to a reference to an object, if you want. 

That's the natural interpretation based on the ordinary meaning of the 
word value. In a language like Python that doesn't have references, 
it's the only sensible interpretation. Otherwise you're forced to argue 
that following a statement x=1, the value of x is something that has no 
existence in Python code.


 But then you need to
 consider what it means to assign that value to a name.

But you need to do that anyway.

Here's a simple C program:

struct Rec
{
  int x;
};

struct Rec a;
struct Rec b;

int main(void)
{
  a.x = 1;
  b = a;
  printf(Before: %d %d\n, a.x, b.x);
  a.x += 1;
  printf(After: %d %d\n, a.x, b.x);
  return 0;
}


It prints:

Before: 1 1
After: 2 1



Here's a simple Python equivalent:

class Rec:
pass

a = Rec()
a.x = 1
b = a
print Before: %d %d % (a.x, b.x)
a.x += 1
print After: %d %d % (a.x, b.x)



It prints:


Before: 1 1
After: 2 2



Anyone want to argue that assignment in Python is the same as in C?



 Obviously it doesn't mean copying the value -- it must mean making the
 name refer to the value somehow.

There's no obviously about it. To anyone who has learned that call-by-
value means that a copy is made, obviously it does mean copying the 
value. If you have learned a different meaning, then you will believe 
differently.


 The same thing happens when the value is passed to a function.

Sure. Calling conventions in Python are the same as name/value binding, 
except that you have a slight extra complication due to having two 
namespaces instead of one.



-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-07 Thread Steven D'Aprano
On Sat, 08 Nov 2008 19:30:17 +1300, greg wrote:

 Something has just occurred to me. If you take the view that the value
 of an expression is an object, then the terms value and object are
 synonymous.

So far so good.

 So if you then insist that Python uses call by object, you're actually
 saying it uses call by value!

Fail!

The terms guy and man are synonymous, but a wise guy and a wise man 
are not.



-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-06 Thread Joe Strout

On Nov 5, 2008, at 12:29 AM, Dennis Lee Bieber wrote:


C++:
void foo(PersonPtr who) {
who-zipcode = 12345;
}


Please show us the type definition of PersonPtr


Sorry, that'd be obvious to anyone experienced in C++, but I shouldn't  
assume.  It would be:


typedef Person* PersonPtr;

It's a pretty standard idiom, precisely because it is so much more  
common to need a variable of the pointer type than of the class type  
itself.



Java:
void foo(Person who) {
who.zipcode = 12345;
}


Please show us the type definition of Person


No.  It's a class, and you can see that it defines a zipcode member;  
nothing more is needed for the sake of this example.  (The Java  
designers realized that needing object reference variables is so  
overwhelmingly more common than needing non-pointer variables, that  
they eliminated the pointer syntax and made every variable of object  
type actually a pointer to the object data, just as in RB, .NET, and  
Python.)



REALbasic/VB.Net:
Sub foo(ByVal who as Person)
who.zipcode = 12345
End Sub


Note they YOU, as the programmer, explicitly told the language to
use a call-by-value


Correct; these languages support both call-by-value and call-by- 
reference.  ByVal is the default, but you can still specify it (as  
I've done here) if you want to be explicit.



-- and you still have not shown us the definition of Person


Right, again, there is nothing you need to know about it not already  
evident from the example.



Python:
def foo(who):
who.zipcode = 12345


Note that there is NO PROGRAMMER CONTROL over the passing mechanism.


Quite right.  (Same too in Java.)  Some languages offer both call-by- 
value and call-by-reference; but Java and Python offer only call-by- 
value.



5. You see that the first three languages above are passing a
reference by value and using that to mutate and object, yet for
reasons still mysterious, the Python example (which has exactly the
same behavior) must be doing something different.


I do not... I see the programmer telling the language that a
reference is to be taken of some object and that this reference is
/then/ to be passed.


Quite right (and that's what I said).  The reference is being passed.   
By value.  And then that reference is used to mutate an object.


AND the programmer is also (C++) explicitly dereferencing (by use of  
-)!


Yep, - is the dereference operator in C++; in Java, RB, .NET, and  
Python, it's ..  Different characters, same meaning.



The syntax, in C/C++ is different for
accessing the parameter by value vs by reference (pointer -- C++ is
smarter in that it allows declaring the parameter as a ref and the
language automatically takes the address on the caller's side, and
dereferences on the called side -- but that notation is STILL a
programmer responsibility).


Careful here -- a ref parameter really is passed by reference; that's  
not the same as passing a pointer by value, which is what's shown  
above.  It's the C++ equivalent of the ByRef keyword in RB/VB.NET.


Java passes /objects/ by reference, but passes native types (base  
numerics) by value


No, it passes everything by value.  who in the Java example is not  
an object; it is an object reference.  It was passed by value.  If it  
were passed by reference, you'd be able to make a swap function that  
exchanges the objects referred to by two variables, but you can't.   
This is explained more fully here:


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

-- can you create a Java example where you pass a base numeric by  
reference?


No, because Java (like Python) has only call-by-value.


By your argument, even FORTRAN is call-by-value.


No, FORTRAN's an oddball: it passes everything by reference.

You obfuscate the mechanics used at the machine language level with  
the semantics of the

language itself.


No, I haven't said anything at all about what's happening at the  
machine language level, and I frankly don't care.  This is about how  
the language behaves.



FORTRAN is the language commonly used to explain call-by-reference!


Quite right.  So, please try to convert any of those FORTRAN  
explanations into Python or Java.  Can't be done.  In C++ or RB/ 
VB.NET, it can be done only by using the special by-reference syntax  
( or ByRef).


I'm not sure where you got the idea that I thought FORTRAN is call-by- 
value.  I never said or implied any such thing.  And the examples  
above aren't meant to prove that those languages are using by-value;  
they're meant to show that mutating an object via a reference passed  
in proves NOTHING about how that reference was passed.  This is to  
invalidate the argument (frequently heard around here) that Python  
must use call-by-reference since you can mutate an object passed to a  
function.


As should be painfully clear by now, that argument is total bunk.  You  
can pass an object reference by value, and use it to 

Re: Finding the instance reference of an object

2008-11-06 Thread Joe Strout

On Nov 4, 2008, at 12:57 PM, Hendrik van Rooyen wrote:


4. You now see how a mutating an object within a function tells you
NOTHING about how the reference to that object was passed.



5. You see that the first three languages above are passing a
reference by value and using that to mutate and object, yet for
reasons still mysterious, the Python example (which has exactly the
same behavior) must be doing something different.


This is dialectic nit picking - WTF makes passing a reference by  
value
different from passing a reference - the salient point is that its  
a reference

that is passed


I know it seems nit-picky on the surface, but it is important.  It is  
the distinction that lets you answer whether:


def foo(x):
   x = Foo()

x = Bar()
foo(x)

...results in x (after the call) now referring to a Foo, or still  
referring to a Bar.


If x is a reference passed by value, then the assignment within the  
foo method can't affect the x that was passed in.  But if it is passed  
by reference, then it does.  (Also, if it is passed by reference, then  
you probably wouldn't be able to pass in a literal or computed value,  
but only a simple variable.)



- would you expect another level of indirection - a reference to
the reference, or what, before you admit that the thing that is  
passed is a

reference and not a copied value of the OBJECT that is of interest.


Um, no, I've admitted that it's a reference all along.  Indeed, that's  
pretty much the whole point: that variables in Python don't contain  
objects, but merely contain references to objects that are actually  
stored somewhere else (i.e. on the heap).  This is explicitly stated  
in the Python docs [1], yet many here seem to want to deny it.


Looks to me that even if there were ten levels of indirection you  
would still
insist that its a pass by value because in the end, its the actual  
memory

address of the first pointer in the queue that is passed.


No, it's entirely possible for an OOP language to have pass by  
reference, and, to put it your way, this adds one more level of  
indirection.  Look at the C++ and RB/VB.NET examples at [2].  But  
Python and Java do not offer this option.


If that is what you mean, it is obviously trivially true - but then  
ALL
calling can only be described as call by value - which makes  
nonsense

of what the CS people have been doing all these years.


That would indeed be nonsense.  But it's also not what I'm saying.   
See [2] again for a detailed discussion and examples.  Call-by-value  
and call-by-reference are quite distinct.



Calling by value is not a useful definition of Pythons behaviour.


It really is, though.  You have to know how the formal parameter  
relates to the actual parameter.  Is it a copy of it, or an alias of  
it?  Without knowing that, you don't know what assignments to the  
formal parameter will do, or even what sort of arguments are valid.   
Answer: it's a copy of it.  Assignments don't affect the actual  
parameter at all.  This is exactly what call by value means.


Best,
- Joe

[1] http://www.python.org/doc/2.5.2/ext/refcounts.html
[2] http://www.strout.net/info/coding/valref/

--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-06 Thread Arnaud Delobelle

I know this thread has grown quite personal for some of its
participants.  I am posting in a spirit of peace and understanding :)

Joe Strout [EMAIL PROTECTED] writes:
[...]
 Um, no, I've admitted that it's a reference all along.  Indeed, that's
 pretty much the whole point: that variables in Python don't contain
 objects, but merely contain references to objects that are actually
 stored somewhere else (i.e. on the heap).  This is explicitly stated
 in the Python docs [1], yet many here seem to want to deny it.

You refer to docs about the *implementation* of Python in C.  This is
irrelevant.

Also, you talk about variables 'containing' something.  In Python,
variables don't contain anything, they're simply names for objects.
'Pass by value' is not relevant to Python as variables do not contain
anything.  'Pass by reference' is not relevant to Python as the language
doesn't have the concept of object reference (in the sense of e.g. C++
reference).

[...]
 Calling by value is not a useful definition of Pythons behaviour.

 It really is, though.  You have to know how the formal parameter
 relates to the actual parameter.  Is it a copy of it, or an alias of
 it?  Without knowing that, you don't know what assignments to the
 formal parameter will do, or even what sort of arguments are valid.
 Answer: it's a copy of it.  Assignments don't affect the actual
 parameter at all.  This is exactly what call by value means.

Here lies, IMHO, the reason why you think you need Python to 'pass by
value'.  As you believe that variables must contain something, you think
that assignment is about copying the content of a variable.  Assignment
in Python is simply giving a new name to an object.

To understand variables (which I prefer to call 'names') and function
calls in Python you need simply to understand that:

  - a variable is a name for an object
  - assignment is naming an object
  - the parameters of a function are local names for the call arguments
(I guess 'pass by object' is a good name).

Now quoting the start of your post:

 On Nov 4, 2008, at 12:57 PM, Hendrik van Rooyen wrote:
 5. You see that the first three languages above are passing a
 reference by value and using that to mutate and object, yet for
 reasons still mysterious, the Python example (which has exactly the
 same behavior) must be doing something different.

 This is dialectic nit picking - WTF makes passing a reference by
 value
 different from passing a reference - the salient point is that its
 a reference
 that is passed

I would say that an oject is passed, not a reference.

 I know it seems nit-picky on the surface, but it is important.  It is
 the distinction that lets you answer whether:

 def foo(x):
x = Foo()

 x = Bar()
 foo(x)

 ...results in x (after the call) now referring to a Foo, or still
 referring to a Bar.

You don't need this to decide.  This is what happens:

x = Bar() # Call this new Bar object 'x'
foo(x)# call function foo with argument the object known as 'x'

# Now, in foo:
def foo(x):   # Call 'x' locally the object passed to foo
x = Foo() # Call 'x' locally this new Foo object.

Obviously after all this, 'x' is still the name of the Bar object
created at the start.


To sum up: for 'pass by value' to make sense in Python you need to
create an unnecessarily complex model of how Python works.  By letting
go of 'pass by value' you can simplify your model of the language
(keeping it correct of course) and it fits in your brain more easily.

Of course your own model is valid but there is a better one which is
easier to grasp for people without a background in C/C++ - like
languages.

-- 
Arnaud
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-06 Thread Aaron Brady
On Nov 6, 1:44 pm, Arnaud Delobelle [EMAIL PROTECTED] wrote:
 I know this thread has grown quite personal for some of its
 participants.  I am posting in a spirit of peace and understanding :)

Hear, hear.

 You refer to docs about the *implementation* of Python in C.  This is
 irrelevant.

 Also, you talk about variables 'containing' something.  In Python,
 variables don't contain anything, they're simply names for objects.
 'Pass by value' is not relevant to Python as variables do not contain
 anything.  'Pass by reference' is not relevant to Python as the language
 doesn't have the concept of object reference (in the sense of e.g. C++
 reference).
...
 I would say that an oject is passed, not a reference.
...
 To sum up: for 'pass by value' to make sense in Python you need to
 create an unnecessarily complex model of how Python works.  By letting
 go of 'pass by value' you can simplify your model of the language
 (keeping it correct of course) and it fits in your brain more easily.

 Of course your own model is valid but there is a better one which is
 easier to grasp for people without a background in C/C++ - like
 languages.

I agree, and I don't think we're giving Joe the proper credit for what
he knows and has worked on.  Furthermore, his understanding of the
implementation of languages is thorough, and you can't have languages
without implementations.  Though, you do not need to understand the
implementation to understand the language.

I haven't thought it through completely, but now that Joe mentions it,
it appears Python behaves the same as C++, if variables can't be
anything but pointers, parameters are all c-b-v, and you can't
dereference the l-h-s of an assignment ( '*a= SomeClass()' ).

When you're explaining Python to a beginner, you have to introduce a
new term either way.  You'll either have to explain pointers, which
there are chapters and chapters on in introductory textbooks; or,
you'll have to explain a new calling mechanism, and give it a name.

I think pointer-by-value would be accurate, but by-value wouldn't be.

 I would say that an oject is passed, not a reference.

I agree, and anything else would be overcomplicated.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-06 Thread Joe Strout

On Nov 5, 2008, at 2:06 PM, Lie wrote:


http://www.strout.net/info/coding/valref/


I'm fed up with you.


I'm sorry -- I'm really not trying to be difficult.  And it's odd that  
you're fed up with me, yet you seem to be agreeing with me on at least  
most points.



In Von Neumann Architecture computers, only pass-by-value is natively
supported. Other idioms are made on top of pass-by-value.


Well, sure.  But a language may or may not naturally support the others.


That's why exclusively pass-by-value languages like C is most flexible
than other exclusively pass-by-insertanythinghere.

BUT the difference is clear, if you want to do pass-by-reference in C
(I prefer to call it faux pass-by-reference), you'd have to manually
find a variable's address, pass it by-value, then dereference the
address.


Agreed.


Compare with VB's ByRef or C++'s , which does all that
_automatically_ for you behind the scene.


Agreed again.


Another example: pass-by-object.


Here's where we depart, I guess.  I think there's no such thing (see http://en.wikipedia.org/wiki/Evaluation_strategy 
 for example, and the dead-tree references I have on hand agree).



I disagree with the term pass-by-object-reference, since the notion
of object reference is unnecessary
in a true pass-by-object mechanism (i.e. we should travel outside VNA
realm for a true pass-by-object mechanism). Problem is: I'm not aware
of any computer architecture that can accommodate pass-by-object
natively or whether such architecture is feasible to be made.


I don't think it's necessary (or helpful) to reach down into the  
architecture or implementation details.  What matters is the behavior  
as seen by the language user.  Variables in a language could hold  
actual object data (in which case a = b would copy the data from b  
into a), or they could hold just references to object data that lives  
elsewhere (in which case a = b would copy that reference, giving you  
two references to the same object).  In Python, they are of course  
just references.


Then, and completely independent of that, variables could be passed  
into a method by value or by reference (or by several other more  
esoteric evaluation strategies that are rarely used, but call by  
object isn't one of them).  Again, it's easy to tell these apart with  
a simple behavioral test.  Python passes its object references by  
value; changes to the formal parameter have no effect on the actual  
parameter.



In pass-by-object, the whole object is passed around, not a copy of
the object like in pass-by-value or a copy of the pointer to the
object like in faux pass-by-reference.


I can't understand what that would mean, unless we imagine the  
variable actually containing the object data; but it doesn't, or a =  
b would copy that data, which clearly it does not.


Understanding that a name in Python is merely a reference to the  
object, and not the object itself, seems to me to be one of the  
fundamental truths that any beginning Python programmer must know.



This makes pass-by-object
actually closer to pass-by-reference than to pass-by-value, since the
notion of VNA's requirement for Object Reference means passing
pointers around. But don't let it confuse you, the pass-by-object
mechanism itself does not recognize Object Reference, unlike pass-by-
reference recognition of reference/pointer.


Sorry, it's confusing me whether I want it to or not.

And here's what I don't understand: object references are so simple,  
why do people go to such great lengths to pretend that Python doesn't  
have them, resulting in a far more complex and convoluted explanation  
that is much harder to understand?



Now that I have clearly defined the line between pass-by-object and
pass-by-value, I'm left with you thinking what's the difference
between pass-by-object and pass-by-reference.


If they're that hard to tell apart, then Python doesn't have either,  
since it is very clear and obvious that Python does not have pass-by- 
reference (since you can't write a function to swap two parameters,  
for example).



In pass-by-reference, names are _mnemonic to location in memory_.
In pass-by-object, names are _mnemonic to objects_.


These would be equivalent if objects live at some location in memory,  
wouldn't they?



In pass-by-reference, when we assign a
value to the name, we'd assign a value _to the location in memory_. In
pass-by-object, when we assign a value to the name, we assign an
object _to the name_. When passing parameters, pass-by-reference
systems passed the memory address and alias that memory address to a
local name. In pass-by-object system, since the object itself has no
idea of its own name, so it is rebound to a local name. You can say
that pass-by-reference system is memory-location-centered, while pass-
by-object system is name-centered.


Hmm. I can only interpret the object is rebound to a local name  
sounds the same to me as a local variable is assigned a reference to  
the 

Re: Finding the instance reference of an object

2008-11-06 Thread Joe Strout

On Nov 6, 2008, at 12:44 PM, Arnaud Delobelle wrote:


I know this thread has grown quite personal for some of its
participants.  I am posting in a spirit of peace and understanding :)


Thanks, I'll do the same.

Um, no, I've admitted that it's a reference all along.  Indeed,  
that's

pretty much the whole point: that variables in Python don't contain
objects, but merely contain references to objects that are actually
stored somewhere else (i.e. on the heap).  This is explicitly stated
in the Python docs [1], yet many here seem to want to deny it.


You refer to docs about the *implementation* of Python in C.  This is
irrelevant.


It's supportive.  I don't understand how/why anybody would deny that  
Python names are references -- it's all over the place, from any  
discussion of reference counting (necessary to understand the life  
cycle of Python object) to understanding the basics of what a = b  
does.  It seems absurd to argue that Python does NOT use references.   
So the official documentation calmly discussing Python references,  
with no caveats about it being internal implementation detail, seemed  
relevant.



Also, you talk about variables 'containing' something.  In Python,
variables don't contain anything, they're simply names for objects.


You say names for, I say references to.  We're saying the same  
thing (though I'm saying it with terminology that is more standard, at  
least in the wider OOP world).



'Pass by value' is not relevant to Python as variables do not contain
anything. 'Pass by reference' is not relevant to Python as the  
language

doesn't have the concept of object reference (in the sense of e.g. C++
reference).


Both are relevant to answering simple questions, like what happens to  
x in this case:


   def foo(spam):
  spam = 5
   foo(x)

This is a basic and fundamental thing that a programmer of a language  
should know.  If it's call-by-reference, then x becomes 5.  If it's  
call-by-value, it does not.


Why the resistance to these simple and basic terms that apply to any  
OOP language?



Here lies, IMHO, the reason why you think you need Python to 'pass by
value'.  As you believe that variables must contain something, you  
think
that assignment is about copying the content of a variable.   
Assignment

in Python is simply giving a new name to an object.


What does give a new name to an object mean?  I submit that it means  
exactly the same thing as assigns the name to refer to the object.   
There certainly is no difference in behavior that anyone has been able  
to point out between what assignment does in Python, and what  
assignment does in RB, VB.NET, Java, or C++ (in the context of object  
pointers, of course).  If the behavior is the same, why should we make  
up our own unique and different terminology for it?



To understand variables (which I prefer to call 'names') and function
calls in Python you need simply to understand that:

 - a variable is a name for an object


A reference to an object, got it.


 - assignment is naming an object


Assigning the reference to the object, yes.


 - the parameters of a function are local names for the call arguments


Agreed; they're not aliases of the call arguments.


   (I guess 'pass by object' is a good name).


Well, I'm not sure why that would be.  What you've just described is  
called pass by value in every other language.



I would say that an oject is passed, not a reference.


That seems to contradict the actual behavior, as well as what you said  
yourself above.  The only way I know how to interpret an object is  
passed is the data of that object is copied onto the stack.  But of  
course that's not what happens.  What actually happens is what you  
said above: a name (reference) is assigned to the object.  The name is  
a reference; it is made to refer to the same thing that the argument  
(actual parameter) referred to.  This is exactly what the reference  
is passed means, nothing more or less.



I know it seems nit-picky on the surface, but it is important.  It is
the distinction that lets you answer whether:

def foo(x):
  x = Foo()

x = Bar()
foo(x)

...results in x (after the call) now referring to a Foo, or still
referring to a Bar.


You don't need this to decide.  This is what happens:

x = Bar() # Call this new Bar object 'x'


In other words, make 'x' refer to this new object.


foo(x)# call function foo with argument the object known as 'x'


Yes.  But what does that mean?  Does the parameter within 'foo' become  
an alias of x, or a copy of it?  That's what we DO need to decide.



# Now, in foo:
def foo(x):   # Call 'x' locally the object passed to foo


I think you mean here that local 'x' is made to refer to the object  
passed to foo.  Agreed.  It is NOT an alias of the actual parameter.   
And that's what we need to know.  So it's not call-by-reference, it's  
call-by-value; the value of x (a reference to whatever object Bar()  
returned) is copied from the 

Re: Finding the instance reference of an object

2008-11-06 Thread Terry Reedy

Aaron Brady wrote:


and you can't have languages without implementations.


This is either a claim that languages are their own implementations, or 
an admission that human brains are the implementation of all languages 
thought of by human brains, coupled with a claim that there cannot be 
languages not thought of by humans, or just wrong in terms of the common 
meaning of algorithmic implementation of an interpreter.  There are many 
algorithm languages without such implementations.  They were once called 
'pseudocode'. (I don't know if that term is still used much.)  Hence my 
oxymoronic definition, a decade ago, of Python as 'executable pseudocode'.


 Though, you do not need to understand the

implementation to understand the language.


Languages are typically defined before there is any implementation. 
They are implemented if they are understood as being worth the effort.



I haven't thought it through completely, but now that Joe mentions it,
it appears Python behaves the same as C++,


Python and C/C++ have completely different object and data models.  You 
and Joe are completely welcome to understand/model Python in terms of 
the C implementation, if you wish, but it not necessary and, I believe, 
a disservice to push such a model on beginners as *the* way to model Python.



if variables can't be
anything but pointers, parameters are all c-b-v, and you can't
dereference the l-h-s of an assignment ( '*a= SomeClass()' ).


I don't understand this.


When you're explaining Python to a beginner, you have to introduce a
new term either way.  You'll either have to explain pointers, which


Python has no concept of pointers.


there are chapters and chapters on in introductory textbooks; or,
you'll have to explain a new calling mechanism, and give it a name.


I disagree.  In everyday life, we have multiple names for objects and 
classes of objects.  We nearly always define procedures in terms of 
generic object classes (common nouns) rather than particular objects. 
We apply procedures by binding generic names to particular objects, by 
associating them with objects, by filling in the named blanks.  This is 
what Python does.  Except for the particular formalized syntax, there is 
nothing new, not even the idea of a specialized procedure language.


def make_cookies(flour, oil, sugar, egg, bowl, spoon, cookie_pan, oven):
flour, oil, and sugar are containers with respectively at least 2 
cups, 1 tablespoon, and 1/4 cup of the indicated material

mix(bowl, spoon, measure(flour, '2 cups'), measure(sugar, '1/4 cup'))
etc

OK, there is one important difference.  The concrete referents for the 
parameters are non-physical information objects rather than physical 
objects.



I would say that an oject is passed, not a reference.



I agree, and anything else would be overcomplicated.


To me, 'pass' implies movement, but in Python, objects don't really have 
a position and hence cannot move.  So I would say that an object is 
associated (with a parameter).  'Associating' is a primitive operation 
for Python interpreters.  If and when all parameters get associated with 
something, the function code is activated.  Then the return object gets 
associated with the call expression in the computation graph.


Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-06 Thread Aaron Brady
On Nov 6, 6:00 pm, Terry Reedy [EMAIL PROTECTED] wrote:
 Aaron Brady wrote:
  and you can't have languages without implementations.

 This is either a claim that languages are their own implementations, or
 an admission that human brains are the implementation of all languages
 thought of by human brains, coupled with a claim that there cannot be
 languages not thought of by humans, or just wrong in terms of the common
 meaning of algorithmic implementation of an interpreter.  There are many
 algorithm languages without such implementations.  They were once called
 'pseudocode'. (I don't know if that term is still used much.)  Hence my
 oxymoronic definition, a decade ago, of Python as 'executable pseudocode'.

I was just saying that Joe has a good idea for one way to implement
Python.

 Python and C/C++ have completely different object and data models.  You
 and Joe are completely welcome to understand/model Python in terms of
 the C implementation, if you wish, but it not necessary and, I believe,
 a disservice to push such a model on beginners as *the* way to model Python.

You're asking about people's thought processes when they write a
program.  In chess, I sometimes think, If I move here, he moves
there, etc., but not always; sometimes I just visualize pieces in
places.  In Python, if I want a function that, say, duplicates the
first and last elements of a sequence type, I visualize one parameter,
and some code that operates on it.

def duper( a ):
  a.insert( 0, a[ 0 ] )
  a.append( a[ -1 ] )

Someone else with no experience, or certain incompatible experience,
might visualize this:

def duper( a ):
  a= a[ 0 ] + a + a[ -1 ]

As you can see, they know a lot of Python already.  What are they
missing?

  if variables can't be
  anything but pointers, parameters are all c-b-v, and you can't
  dereference the l-h-s of an assignment ( '*a= SomeClass()' ).

 I don't understand this.

If you restricted a C program as follows:
  - variables can only be pointers
  - no pointers to pointers
  - no dereferencing l-h-s of assignment statements

It would look at the very least a lot like Python, or as Joe holds,
exactly like Python.

snip.

 I disagree.  In everyday life, we have multiple names for objects and
 classes of objects.  We nearly always define procedures in terms of
 generic object classes (common nouns) rather than particular objects.
 We apply procedures by binding generic names to particular objects, by
 associating them with objects, by filling in the named blanks.  This is
 what Python does.  Except for the particular formalized syntax, there is
 nothing new, not even the idea of a specialized procedure language.

To examine the natural language (NL) equivalents of these issues a
little.

Here's a question I posed to Joe:

a) 'Fido' is a reference to a dog
b) Fido is a reference to a dog
c) 'Fido' is the name of a dog
d) Fido is the name of a dog
e) 'Fido' is a dog
f) Fido is a dog

Which are true?

I have no problems with (c) and (f), and many natural languages
(possibly being strictly spoken) do not distinguish (c) from (d).
Similarly,

Old McDonald had a dog and Bingo was it's name.
(*) Old McDonald had a dog and Bingo was it.  (* marks non-standard)
(*) Old McDonald had a dog and it was Bingo.

I want to give a code name to Fido: Rex.  What language do I use to
inform my audience (spies), and what statements are subsequently
true?  Then, I want to write instructions to friends on how to walk
dogs in my neighborhood, still in natural language.

_How to walk a dog_
  Take the dog out the door
  Turn right at the end of the drive
  etc.

Nothing mysterious.  Same thing with instructions for vaccinating
them.  However, if I want to model dogs, simulate them, etc., I'll
keep some running state information about them: think its chart at the
vet.

Dog:
  Fido:
Last walked: 10 a.m.
Needs to be walked: False

At 4 p.m., I'm going through the charts, and I notice Fido hasn't been
walked, so I change the 'Needs to be walked' entry to true.

Then some members of spies walks into the vet, and ask if Rex needs
to be walked.

What things in this story are names, variables, dogs, references,
objects, pointers, types, classes, procedures, functions, arguments,
parameters, formal parameters, by-value parameters, by-reference
parameters, by-share parameters, etc.?  How many names does Fido have,
what are they, what is Fido, what is Rex, etc.?  Keep in mind there
are seldom quotes in spoken language; people have to make gestures or
be explicit in such cases as they need to indicate their presence.

Quote Fido quote is the name of a dog, but Fido is not.  (Actual
transcription.)

Keep answers to less than 500 words.  Also, reevaluate the uses of
'the' and 'a' in the multiple choice question: Is 'Fido' the name of a
dog, a name of a dog, or a name of the dog?

 def make_cookies(flour, oil, sugar, egg, bowl, spoon, cookie_pan, oven):
      flour, oil, and sugar are containers with respectively at least 2
 

Re: Finding the instance reference of an object

2008-11-06 Thread Steven D'Aprano
On Thu, 06 Nov 2008 09:59:37 -0700, Joe Strout wrote:

 that's
 pretty much the whole point: that variables in Python don't contain
 objects, but merely contain references to objects that are actually
 stored somewhere else (i.e. on the heap).

You're wrong, Python variables don't contain *anything*. Python variables 
are names in a namespace. But putting that aside, consider the Python 
code x = 1. Which statement would you agree with?

(A) The value of x is 1.

(B) The value of x is an implementation-specific thing which is 
determined at runtime. At the level of the Python virtual machine, the 
value of x is arbitrary and can't be determined.

If you answer (A), then your claim that Python is call-by-value is false. 
If you answer (B), then your claim that Python is call-by-value is true 
but pointless, obtuse and obfuscatory.



 This is explicitly stated in
 the Python docs [1], yet many here seem to want to deny it.

 [1] http://www.python.org/doc/2.5.2/ext/refcounts.html


You have a mysterious and strange meaning of the word explicitly. Would 
you care to quote what you imagine is this explicit claim?



 Looks to me that even if there were ten levels of indirection you would
 still
 insist that its a pass by value because in the end, its the actual
 memory
 address of the first pointer in the queue that is passed.
 
 No, it's entirely possible for an OOP language to have pass by
 reference, and, to put it your way, this adds one more level of
 indirection.  Look at the C++ and RB/VB.NET examples at [2].  But Python
 and Java do not offer this option.

Yes, you are right, Python does not offer pass by reference. The 
canonical test for call by reference behaviour is to write a function 
that does this:

x = 1
y = 2
swap(x, y)
assert x == 2 and y == 1

If you can write such a function, your language may be call-by-reference. 
If you can't, it definitely isn't c-b-r. You can't write such a function 
in standard Python, so Python isn't c-b-r.


The canonical test for call by value semantics is if you can write a 
function like this:

x = [1]  # an object that supports mutation
mutate(x)
assert x == [1]

If mutations to an argument in a function are *not* reflected in the 
caller's scope, then your language may be call-by-value. But if mutations 
are visible to the caller, then your language is definitely not c-b-v.

Python is neither call-by-reference nor call-by-value.

 
 If that is what you mean, it is obviously trivially true - but then ALL
 calling can only be described as call by value - which makes nonsense
 of what the CS people have been doing all these years.
 
 That would indeed be nonsense.  But it's also not what I'm saying. See
 [2] again for a detailed discussion and examples.  Call-by-value and
 call-by-reference are quite distinct.

And also a false dichotomy. 


 Calling by value is not a useful definition of Pythons behaviour.
 
 It really is, though.  You have to know how the formal parameter relates
 to the actual parameter.  Is it a copy of it, or an alias of it?

And by definition, call by value means that the parameter is a copy. So 
if you pass a ten megabyte data structure to a function using call-by-
value semantics, the entire ten megabyte structure is copied.

Since this does not happen in Python, Python is not a call-by-value 
language. End of story.


 
 Without knowing that, you don't know what assignments to the formal
 parameter will do, or even what sort of arguments are valid. Answer:
 it's a copy of it.  

Lies, all lies. Python doesn't copy variables unless you explicitly ask 
for a copy. That some implementations of Python choose to copy pointers 
rather than move around arbitrarily large blocks of memory instead is an 
implementation detail. It's an optimization and irrelevant to the 
semantics of argument passing in Python.



 Assignments don't affect the actual parameter at
 all.  This is exactly what call by value means.

Nonsense. I don't know where you get your definitions from, but it isn't 
a definition anyone coming from a background in C, Pascal or Fortran 
would agree with.




-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-06 Thread Joe Strout
First, I want to thank everyone for your patience -- I think we're  
making progress towards a consensus.


On Nov 6, 2008, at 8:48 PM, Steven D'Aprano wrote:


that's
pretty much the whole point: that variables in Python don't contain
objects, but merely contain references to objects that are actually
stored somewhere else (i.e. on the heap).


You're wrong, Python variables don't contain *anything*. Python  
variables

are names in a namespace.


I think we're saying the same thing.  What's a name?  It's a string of  
characters used to refer to something.  That which refers to something  
is a reference.  The thing it refers to is a referent.  I was trying  
to avoid saying the value of an object reference is a reference to an  
object since that seems tautological and you don't like my use of the  
word value, but I see you don't like contains either.


Maybe we can try something even wordier: a variable in Python is, by  
some means we're not specifying, associated with an object.  (This is  
what I mean when I say it refers to the object.)  Can we agree that  
far?


Now, when you pass a variable into a method, the formal parameter gets  
associated with same object the actual parameter was associated with.   
I like to say that the object reference gets copied into the formal  
parameter, since that's a nice, simple, clear, and standard way of  
describing it.  I think you object to this way of saying it.  But are  
we at least in agreement that this is what happens?



But putting that aside, consider the Python
code x = 1. Which statement would you agree with?

(A) The value of x is 1.


Only speaking loosely (which we can get away with because numbers are  
immutable types, as pointed out in the last section of [1]).



(B) The value of x is an implementation-specific thing which is
determined at runtime. At the level of the Python virtual machine, the
value of x is arbitrary and can't be determined.


Hmm, this might be true to somebody working at the implementation  
level, but I think we're all agreed that that's not the level of this  
discussion.  What's relevant here is how the language actually  
behaves, as observable by tests written in that language.


If you answer (A), then your claim that Python is call-by-value is  
false.


Correct.

If you answer (B), then your claim that Python is call-by-value is  
true

but pointless, obtuse and obfuscatory.


Correct again.  My answer is:

(C) The value of x is a reference to an immutable object with the  
value of 1.  (That's too wordy for casual conversation so we might  
casually reduce this to (A), as long as we all understand that (A) is  
not actually true.  It's a harmless fiction as long as the object is  
immutable; it becomes important when we're dealing with mutable  
objects.)



This is explicitly stated in
the Python docs [1], yet many here seem to want to deny it.



[1] http://www.python.org/doc/2.5.2/ext/refcounts.html


You have a mysterious and strange meaning of the word explicitly.  
Would

you care to quote what you imagine is this explicit claim?


A few samples: The chosen method is called reference counting. The  
principle is simple: every object contains a counter, which is  
incremented when a reference to the object is stored somewhere, and  
which is decremented when a reference to it is deleted. When the  
counter reaches zero, the last reference to the object has been  
deleted and the object is freed.   ...Python uses the traditional  
reference counting implementation...


This seems like a point we really shouldn't need to argue.  Do you  
really want to defend the claim that Python does not use references?



Yes, you are right, Python does not offer pass by reference. The
canonical test for call by reference behaviour is to write a  
function

that does this:

x = 1
y = 2
swap(x, y)
assert x == 2 and y == 1

If you can write such a function, your language may be call-by- 
reference.
If you can't, it definitely isn't c-b-r. You can't write such a  
function

in standard Python, so Python isn't c-b-r.


Whew!  That's a relief.  A week ago (or more?), it certainly sounded  
like some here were claiming that Python is c-b-r (usually followed by  
some extended hemming and hawing and except-for-ing to explain why you  
couldn't do the above).



The canonical test for call by value semantics is if you can write a
function like this:

x = [1]  # an object that supports mutation
mutate(x)
assert x == [1]

If mutations to an argument in a function are *not* reflected in the
caller's scope, then your language may be call-by-value. But if  
mutations

are visible to the caller, then your language is definitely not c-b-v.


Aha.  So, in your view, neither C, nor C++, nor Java, nor VB.NET are c- 
b-v, since all of those support passing an object reference into a  
function, and using that reference to mutate the object.


Your view is at odds with the standard definition, though; in fact I'm  
pretty sure we could dig 

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

2008-11-06 Thread Steve Holden
Joe Strout wrote:
 On Nov 6, 2008, at 12:44 PM, Arnaud Delobelle wrote:
 
 I know this thread has grown quite personal for some of its
 participants.  I am posting in a spirit of peace and understanding :)
 
 Thanks, I'll do the same.
 
That's good to hear. Your arguments are sometimes pretty good, and
usually well made, but there's been far too much insistence on all sides
about being right and not enough on reaching agreement about how
Python's well-defined semantics for assignment and function calling
should best be described.

In other words, it's a classic communication problem.

 Um, no, I've admitted that it's a reference all along.  Indeed, that's
 pretty much the whole point: that variables in Python don't contain
 objects, but merely contain references to objects that are actually
 stored somewhere else (i.e. on the heap).  This is explicitly stated
 in the Python docs [1], yet many here seem to want to deny it.

 You refer to docs about the *implementation* of Python in C.  This is
 irrelevant.
 
 It's supportive.  I don't understand how/why anybody would deny that
 Python names are references -- it's all over the place, from any
 discussion of reference counting (necessary to understand the life
 cycle of Python object) to understanding the basics of what a = b
 does.  It seems absurd to argue that Python does NOT use references.  So
 the official documentation calmly discussing Python references, with no
 caveats about it being internal implementation detail, seemed relevant.
 
I must say I find it strange when people try to contradict my assertion
that Python names are references to objects, when the (no pun intended)
reference implementation of the language uses reference counting to
track how many assignments have been made.

 Also, you talk about variables 'containing' something.  In Python,
 variables don't contain anything, they're simply names for objects.
 
Though there is an equally vociferous faction who will happily jump up
and down all day shouting objects don't have names, a tendency I have
myself been known to indulge from time to time (but usually only when
some novitiate asks how they can find out what the name of an object
is). Being of the old school, I do tend to think of Python names as
being reference variables in the sense of Algol 68. Thus they are
fixed-size and frequently of limited lifetime. Since assignment (whether
by name binding or to a container element) copies the reference, and
since strong references keep objects alive, this is one way to explain
why Python doesn't suffer from C++'s dangling pointer issue.

 You say names for, I say references to.  We're saying the same thing
 (though I'm saying it with terminology that is more standard, at least
 in the wider OOP world).
 
Naughty, naughty, there's that little I'm right, you're wrong thing
sneaking in again. I don't want to have to get the clue stick out here ...

 'Pass by value' is not relevant to Python as variables do not contain
 anything. 'Pass by reference' is not relevant to Python as the language
 doesn't have the concept of object reference (in the sense of e.g. C++
 reference).

Variables do not contain anything seems to be a little extreme here.
They must store information of some sort, or no Python program could
ever produce a useful output. And while the concept of object
reference may not exist in the language, it is definitely valid for
implementers.

Interestingly, while variable isn't an indexed term in the (2.6)
documentation, reference count appears in the glossary and the
Language Reference Manual (again, no pun intended) explicitly states in
its discussion of Python's data model (vis a vis the exact meaning of
immutability) that container objects contain references to other
objects. It shortly thereafter mentions the reference-counting technique
of the CPython implementation, but does not claim it as part of the
language.

The same section also mentions reference to 'external' resources such
as files or windows ... and references to other objects.

Interestingly it is also made explicit that for immutable types,
operations that compute new values may return a reference to any
existing object with the same type and value, while for mutable objects
this is not allowed (and if any reader disagrees that the reasons for
this are obvious their part in this thread was long since over).

There's even a built-in type called a weak reference.

So any argument that the language doesn't have the concept of object
reference (in the sense of e.g. C++ reference) is simply stating the
obvious: that Python has no way to declare reference variables. I would
argue myself that it has no need of such a mechanism precisely because
names are object references, and I'd like to hear counter-arguments.
Consider my memory short -- I have a large dose of crotchety to go with
that it you'd like.

 
 Both are relevant to answering simple questions, like what happens to x
 in this case:
 
def foo(spam):
   

Re: Finding the instance reference of an object

2008-11-06 Thread Terry Reedy

Aaron Brady wrote:

On Nov 6, 6:00 pm, Terry Reedy [EMAIL PROTECTED] wrote:



'Associating' is a primitive operation for Python interpreters.


Interesting.  If I may be so bold as to ask, is it for C code, C
compilers, and/or C programs?


Sorry, I should have specified for the abstract definition of a Python 
interpreter, and perhaps for people.  Computer programs need an 
implementation in terms of computer memory, etc.


--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-06 Thread Steve Holden
Steven D'Aprano wrote:
 On Thu, 06 Nov 2008 09:59:37 -0700, Joe Strout wrote:
[...]
 And by definition, call by value means that the parameter is a copy. So 
 if you pass a ten megabyte data structure to a function using call-by-
 value semantics, the entire ten megabyte structure is copied.
 
 Since this does not happen in Python, Python is not a call-by-value 
 language. End of story.
 
 
  
 Without knowing that, you don't know what assignments to the formal
 parameter will do, or even what sort of arguments are valid. Answer:
 it's a copy of it.  
 
 Lies, all lies. Python doesn't copy variables unless you explicitly ask 
 for a copy. That some implementations of Python choose to copy pointers 
 rather than move around arbitrarily large blocks of memory instead is an 
 implementation detail. It's an optimization and irrelevant to the 
 semantics of argument passing in Python.
[...]

Are you sure you meant to write this?

regards
 Steve
-- 
Steve Holden+1 571 484 6266   +1 800 494 3119
Holden Web LLC  http://www.holdenweb.com/

--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-06 Thread Steve Holden
Joe Strout wrote:
 First, I want to thank everyone for your patience -- I think we're
 making progress towards a consensus.
 
Phew.
 
 But putting that aside, consider the Python
 code x = 1. Which statement would you agree with?

 (A) The value of x is 1.
 
 Only speaking loosely (which we can get away with because numbers are
 immutable types, as pointed out in the last section of [1]).
 
I'd agree this is a valid way to describe the post-condition of the
assignment.

 (B) The value of x is an implementation-specific thing which is
 determined at runtime. At the level of the Python virtual machine, the
 value of x is arbitrary and can't be determined.
 
 Hmm, this might be true to somebody working at the implementation level,
 but I think we're all agreed that that's not the level of this
 discussion.  What's relevant here is how the language actually behaves,
 as observable by tests written in that language.
 
I'd actually say x contains a reference to 1, claim that was
equivalent to (A) above and cite Humpty Dumpty as my justification [1].

 If you answer (A), then your claim that Python is call-by-value is false.
 
 Correct.
 
 If you answer (B), then your claim that Python is call-by-value is true
 but pointless, obtuse and obfuscatory.
 
 Correct again.  My answer is:
 
 (C) The value of x is a reference to an immutable object with the value
 of 1.  (That's too wordy for casual conversation so we might casually
 reduce this to (A), as long as we all understand that (A) is not
 actually true.  It's a harmless fiction as long as the object is
 immutable; it becomes important when we're dealing with mutable objects.)
 
I am unsure here as to why you find it necessary to refer to 1's
immutability. How does this alter the essence of the situation?

[...]
 
 Not that I'm trying to argue from authority; I'm trying to argue from
 logic.  I suspect, though, that your last comment gets to the crux of
 the matter, and reinforces my guess above: you don't think c-b-v means
 what most people think it means.  Indeed, you don't think any of the
 languages shown at [1] are, in fact, c-b-v languages.  If so, then we
 should focus on that and see if we can find a definitive answer.
 
You're right. Observable progress, I think.

regards
 Steve

[1] http://www.sundials.org/about/humpty.htm
-- 
Steve Holden+1 571 484 6266   +1 800 494 3119
Holden Web LLC  http://www.holdenweb.com/

--
http://mail.python.org/mailman/listinfo/python-list


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

2008-11-06 Thread Ben Finney
Steve Holden [EMAIL PROTECTED] writes:

 One of the reasons for Python's continue march towards world
 domination (allow me my fantasies) is its consistent simplicity.
 Those last two words would be my candidate for the definition of
 Pythonicity.

+1 QOTW

-- 
 \  Eccles: “I'll get [the job] too, you'll see. I'm wearing a |
  `\Cambridge tie.”  Greenslade: “What were you doing there?”  |
_o__)   Eccles: “Buying a tie.” —The Goon Show, _The Greenslade Story_ |
Ben Finney
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-05 Thread Hendrik van Rooyen
 Joe Strout [EMAIL PROTECTED] wrote:


 4. You now see how a mutating an object within a function tells you
 NOTHING about how the reference to that object was passed.

 5. You see that the first three languages above are passing a
 reference by value and using that to mutate and object, yet for
 reasons still mysterious, the Python example (which has exactly the
 same behavior) must be doing something different.

This is dialectic nit picking - WTF makes passing a reference by value
different from passing a reference - the salient point is that its a reference
that is passed - would you expect another level of indirection - a reference to
the
reference, or what, before you admit that the thing that is passed is a
reference
and not a copied value of the OBJECT that is of interest.

Looks to me that even if there were ten levels of indirection you would still
insist that its a pass by value because in the end, its the actual memory
address of the first pointer in the queue that is passed.  If that is what you
mean,
it is obviously trivially true - but then ALL calling can only be described as
call by value - which makes nonsense of what the CS people have been
doing all these years.

Calling by value is not a useful definition of Pythons behaviour.

- Hendrik



--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-05 Thread Terry Reedy

Dennis Lee Bieber wrote:


I'm sure all the programmers using FORTRAN for the last 50 years
will be very surprised to hear that it uses call-by-value!


That should be 'last 31 years'.  Fortran IV *was* call-by-value, as 
least for scalars.  I remember spending a couple of hours tracking down 
an obscure 'bug' in a once-working program when I ran it with F77. (I 
had not noticed the call-by-reference switch.) The reason was, as I 
remember, 'x = -x' in a function.  I never forgot the difference.



I've used it for 30 years


Then you apparently missed the switch ;-).

tjr


--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-05 Thread Lie
On Nov 4, 9:33 am, Joe Strout [EMAIL PROTECTED] wrote:
 On Nov 3, 2008, at 5:27 PM, Marc 'BlackJack' Rintsch wrote:

  Maybe this is a surprise for you, because we haven't discussed this in
  much detail in this group lately, but it applies to Python which does
  call-by-object or call-by-sharing.  ;-)

 There's no such thing.  Those are just terms made up by the Python  
 community to in place of the more standard call-by-value terminology  
 to make Python seem more mysterious than it really is.  I guess you  
 can call it purple bananas if you want, but the behavior is exactly  
 the same as what every other language calls call-by-value.

 But I really am trying not to continue this debate.  So that's my last  
 reply about it for tonight, I promise.  :)

 Cheers,
 - Joe
 http://www.strout.net/info/coding/valref/

I'm fed up with you.

In Von Neumann Architecture computers, only pass-by-value is natively
supported. Other idioms are made on top of pass-by-value.

That's why exclusively pass-by-value languages like C is most flexible
than other exclusively pass-by-insertanythinghere.

BUT the difference is clear, if you want to do pass-by-reference in C
(I prefer to call it faux pass-by-reference), you'd have to manually
find a variable's address, pass it by-value, then dereference the
address. Compare with VB's ByRef or C++'s , which does all that
_automatically_ for you behind the scene.

Another example: pass-by-object. I disagree with the term pass-by-
object-reference, since the notion of object reference is unnecessary
in a true pass-by-object mechanism (i.e. we should travel outside VNA
realm for a true pass-by-object mechanism). Problem is: I'm not aware
of any computer architecture that can accommodate pass-by-object
natively or whether such architecture is feasible to be made.
Solution: Emulate such architecture on a VNA computer. Limitations:
pass-by-object implementation on a VNA computer requires the notion of
object reference/pointer because VNA computers cannot pass object, it
can only pass numbers.

In pass-by-object, the whole object is passed around, not a copy of
the object like in pass-by-value or a copy of the pointer to the
object like in faux pass-by-reference. This makes pass-by-object
actually closer to pass-by-reference than to pass-by-value, since the
notion of VNA's requirement for Object Reference means passing
pointers around. But don't let it confuse you, the pass-by-object
mechanism itself does not recognize Object Reference, unlike pass-by-
reference recognition of reference/pointer.

Now that I have clearly defined the line between pass-by-object and
pass-by-value, I'm left with you thinking what's the difference
between pass-by-object and pass-by-reference. In pass-by-reference,
names are _mnemonic to location in memory_. In pass-by-object, names
are _mnemonic to objects_. In pass-by-reference, when we assign a
value to the name, we'd assign a value _to the location in memory_. In
pass-by-object, when we assign a value to the name, we assign an
object _to the name_. When passing parameters, pass-by-reference
systems passed the memory address and alias that memory address to a
local name. In pass-by-object system, since the object itself has no
idea of its own name, so it is rebound to a local name. You can say
that pass-by-reference system is memory-location-centered, while pass-
by-object system is name-centered.

To summarize, the key bit you're missing is built-in _automatic_
abstraction from pass-by-value. All pass-by-insertanything except
pass-by-value is an emulation over an architecture that can only
natively pass-by-value. pass-by-reference is emulated in C, C++, and
VB by passing memory address/pointer but C isn't a by-ref system
because C doesn't provide the automatization. What makes python's
parameter passing called as pass-by-object is because python provides
the automatization to make it seems that you can do true pass-by-
object.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-04 Thread Craig Allen

 If the assert statement fails (and it does), then no copy was made and
 Python is not call-by-value.

 So Python is not call-by-value, and it's not call-by-reference, so ...
 either Python doesn't exist, or it uses a different calling convention.


coming from C/C++ Python seemed to me call by reference, for the
pragmatic reason you said, modificaitons to function arguments do
affect the variable in the caller.  The confusing part of this then
comes when immutable objects are passed in. You still get a reference,
but rather than complaining if you change the value of that parameter
at might happen if immutible was const and the code was const-
correct. Honestly I understand how this can change the callBy paradigm
I don't see it that way (though I've duly remembers call-by-sharing
and call-by-object) for communication purposes).  I see it as a factor
of the way variable names are rebound, that is, the quirk I remember
is not about how entities are passed to functions, but the quirk of
how python deals with modifications to immutibles.

That is, python lets you change object references pointing to
immutibles, which looks like changing the value referenced,  by
rebinding.

So is that objectionable?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-04 Thread Mel
Craig Allen wrote:
 That is, python lets you change object references pointing to
 immutibles, which looks like changing the value referenced,  by
 rebinding.
 
 So is that objectionable?

OK once in a while, but it wouldn't do for everyday.

Python 2.5.2 (r252:60911, Jul 31 2008, 17:28:52)
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
Type help, copyright, credits or license for more information.
# Case A:
 a=2
 b=3
 a+b
5
# Case B:
 id(a)
135720748
 id(b)
135720736
 id(a+b)
135720712
 id(a)+id(b)
271441484

In talking about Python programs, we'd really like to talk like case A. 
Meaningful values are tagged with names, passed around, operated on.  We
get our result and leave.  Case B adds a level of indirection that, if we
mention it, just obscures our actual task of summing two numbers.

Consider the fragment

def f (x, y):
return x+y
a=2
b=3
c = f(a, b)

We can imagine a cross-namespace assignment operator (which we could write
=\= if we needed more weird glyphs.)  It works exactly like ordinary
assignment except that the LHS is evaluated in a different namespace from
the RHS.  We could use our new operator to trace the execution of this code
fragment.  The core of it would be

x =\= a # outer to inner assignment
y =\= b
c =/= x+y   # inner to outer assignment

It's ordinary assignment all the way, except for being from an outer to an
inner, or from an inner to an outer namespace.  Note how changing to
mutable arguments makes no difference (literal arguments this time):

c = f ([2], [3])

x =\= [2]
y =\= [3]
c =/= x+y

Replacing =\= and =/= with = loses us our cross-namespace conceit, but the
code still runs and does what Python code does.

So why import the wrong terminology from some other field, then try to save
it by mangling the definition of 'value' so that it's no use in discussing 
what a program is supposed to do?

ob: Python, I refer you to the _Beyond the Fringe_ sketch Portrait from
Memory, a reminiscence by a pseudo Bertrand Russell (Moore, have you some
apples in that basket?.)  You want to have to talk like this all the time? 
See what I mean?

--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-04 Thread Joe Strout

On Nov 4, 2008, at 7:42 AM, Craig Allen wrote:


coming from C/C++ Python seemed to me call by reference, for the
pragmatic reason you said, modificaitons to function arguments do
affect the variable in the caller.  The confusing part of this then
comes when immutable objects are passed in.


Yes, you stepped in the wrong direction right away and led yourself  
into a morass of contradictions.


The correct way to look at it is that a Python reference is like a C++  
pointer.  C++ pointers are passed by value (unless you add  to  
explicitly make a parameter by-reference), yet you can still use them  
to mutate the objects they point to, right?  Same thing in Python.   
Nothing at all mysterious going on here.  Compare this:


typedef Spam* SpamPtr;   // (where Spam is some class)
// ...
void foo(SpamPtr spam)
{
spam-count = 4;
}

When you call foo, it modifies the spam object passed in, even though  
the parameter is by-value.  How?  Because (looking more carefully),  
you didn't actually pass in a Spam object; you passed in a POINTER TO  
a Spam object.  That pointer remained unchanged.  You just used the  
pointer to change some other data living on the heap.  This is the  
case exactly equivalent to Python:


def foo(spam):
spam.count = 4;

Same thing here; the variable you pass in is a reference to a Spam  
object, and while that reference remains unchanged by the call, it is  
used to change some other data that lives on the heap.


Here's a C++ example that has no analog in Python, because it uses  
call-by-reference:


void throwOut(SpamPtr spam)
{
printf(throwing out %s\n, spam-brand);
delete spam;
spam = nil;
}

Now here, when you invoke throwOut on a SpamPtr, your own SpamPtr  
variable (the one that you pass in) actually gets set to nil.  That's  
because the formal parameter here is just an alias of the actual  
parameter.  You can't do that in Python; this attempt:


def throwOut(spam):
print throwing out %s\n, spam.brand
spam = nil

would entirely fail to have any effect whatsoever on the Spam  
reference you pass in.  spam here is just a local variable within  
the throwOut function, which has no connection to the variable passed  
in other than it gets a copy of its value (i.e., it initially refers  
to the same object as the actual parameter).  This doesn't work, and  
the C++ throwOut function has no analog in Python, because Python has  
no call-by-reference.


Here's another C++ example that has no analog in Python, because it  
passes an object directly on the stack rather than a reference to it:


void bar(Spam spam)
{
spam.count = 5;
}

This is the one that I know particularly confuses some users, because  
it LOOKS like what you could do in Python, and has the same behavior  
on the surface.  But it's not analogous at all, because the spam  
local variable here (and presumably the one in the calling context) is  
an object stored directly on the stack, rather than a reference to an  
object on the heap.  Python can't do that (nor can Java, nor  
REALbasic, etc.).  This example is also call-by-value, but the value  
in this case is a type that has no analog in Python.  Python object  
variables are references to objects on the heap, just like pointers in  
C++ to objects created with new.  So this example is a red herring.


I'd be very interested in hearing whether, as a C/C++ user, the above  
explanation is clear and makes sense to you.


Thanks,
- Joe


--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-04 Thread Bruno Desthuilliers

Joe Strout a écrit :

On Nov 3, 2008, at 5:27 PM, Marc 'BlackJack' Rintsch wrote:


Maybe this is a surprise for you, because we haven't discussed this in
much detail in this group lately, but it applies to Python which does
call-by-object or call-by-sharing.  ;-)


There's no such thing.  Those are just terms made up by the Python 
community


Did you read *any* of the many answers in this thread ? This term comes 
from lisp, and existed years before Python.


to in place of the more standard call-by-value terminology 
to make Python seem more mysterious than it really is.


Looks a bit paranoid to me.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-04 Thread Craig Allen
On Nov 4, 11:06 am, Joe Strout [EMAIL PROTECTED] wrote:
 On Nov 4, 2008, at 7:42 AM, Craig Allen wrote:

  coming from C/C++ Python seemed to me call by reference, for the
  pragmatic reason you said, modificaitons to function arguments do
  affect the variable in the caller.  The confusing part of this then
  comes when immutable objects are passed in.

 Yes, you stepped in the wrong direction right away and led yourself  
 into a morass of contradictions.

 The correct way to look at it is that a Python reference is like a C++  
 pointer.  C++ pointers are passed by value (unless you add  to  
...
 I'd be very interested in hearing whether, as a C/C++ user, the above  
 explanation is clear and makes sense to you.


joe, yes, it makes perfect sense. In my defense my priority was
figuring out what was going on in terms of what happens passing in
various types of arguments, rather than what things are called. Also,
as a C/C++ programmer my perspective is that the program is the
interpreter, and so I try to think what the interpreter is doing.
This is ke because after 15 years of statically linked languages (no
one calls them this any more due to dynamically linked libraries) you
get used to things evaporating at compile time, the name x for a
variable has no status as a real entity at run time. It is a name
through which you communicate with the compiler only, the compiler has
no need to represent it in the runtime program.  I think a lot of this
language history is based on terminology that does not have to
consider this name as a real entity at runtime.

When you consider the status of the entity x in x=1 in python, it
is a pointer, and python looks like pass by value.

The need for a different name comes from the fact that using pointers
ubiquitously like this leads to behavior much more like pass by
reference.

I'm open to pass-by-sharing, or pass-by-object, but neither is
perticularly intuitive, not as obvious in meaning as pass-by-val or
pass-by-reference (or call-by-xxx). I suppose I'd like pass-by-name as
more a description, as name to me has a similar sense to pointer, at
least in a language that preserves the name as a runtime entitity
(making C/C++ languages which compile away names).

What happens in python is clear to me, I think I understand what the
program, CPython is doing... the language still needs to settle.

Thanks for the reply, it does help me find a better way to discuss
what I understand about python and calling mechanics in general.

cheers,
craig
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-04 Thread Marc 'BlackJack' Rintsch
On Tue, 04 Nov 2008 09:16:05 -0800, Craig Allen wrote:

 I'm open to pass-by-sharing, or pass-by-object, but neither is
 perticularly intuitive, not as obvious in meaning as pass-by-val or
 pass-by-reference (or call-by-xxx). I suppose I'd like pass-by-name as
 more a description, as name to me has a similar sense to pointer, at
 least in a language that preserves the name as a runtime entitity
 (making C/C++ languages which compile away names).

But call-by-name has a very different meaning from call-by-value, call-by-
reference, or call-by-object or call-by-sharing.  Call-by-name injects 
the expression used to call into the called function and evaluates it 
every time the argument is accessed within the function.

Ciao,
Marc 'BlackJack' Rintsch
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-04 Thread Hendrik van Rooyen
Aaron Brady [EMAIL PROTECTED] wrote:

I think we can conclude that Python passes by reference, since a
function can modify objects that were passed in to it.

Sort of - if the modification is by side effect - so you
can append to a list, for instance.

However, if you use the passed param name on the left
of an assignment statement, you get a new local object.
I think it is this that lies at the root of the confusion.

- Hendrik



--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-04 Thread Steven D'Aprano
On Mon, 03 Nov 2008 19:33:52 -0700, Joe Strout wrote:

 On Nov 3, 2008, at 5:27 PM, Marc 'BlackJack' Rintsch wrote:
 
 Maybe this is a surprise for you, because we haven't discussed this in
 much detail in this group lately, but it applies to Python which does
 call-by-object or call-by-sharing.  ;-)
 
 There's no such thing.  Those are just terms made up by the Python
 community to in place of the more standard call-by-value terminology
 to make Python seem more mysterious than it really is.

I call bullshit on you. We've already shown you that the term call-by-
sharing (a.k.a. call-by-object or call-by-object-sharing) goes back to 
the 1970s and such computer scientists as Barbara Liskov. The language 
CLU used the term back in 1974, and it is possible that CLU wasn't the 
first language to use it. That's over fifteen years before the first 
release of Python.

This is not the first time it's been pointed out to you. And it won't be 
the last. And I predict that it will make no difference to you at all: 
you will still continue to pretend that Liskov et al aren't even worth 
acknowledging, and you will continue to make the asinine definition that 
the value of x following x = 1 is 0x97b3250 rather than 1.



 I guess you can
 call it purple bananas if you want, but the behavior is exactly the
 same as what every other language calls call-by-value.

Again, I call bullshit. Python's behaviour is not the same as what 
Pascal, or C, calls call-by-value. It is what many Java people call call-
by-value, because they make the same idiotic definition that the value 
of a variable is some arbitrary and hidden reference to the thing of 
interest:

Java is call-by-value, where value means a reference to the actual 
value, except for primitives, where the value is the actual value.

It is an idiotic definition, the sort of thing that only a very smart 
person can make, twisting the plain and intuitive meaning of value (what 
is denoted by a symbol) just to avoid having to accept that there are 
more things in reality than their pet theory includes.

It's not we Python folk who are guilty of misusing terminology, it is you 
and your fellow VB and Java folk who are misusing the term call-by-value 
to describe something which is nothing like call-by-value in Pascal and 
C. There is a simple test you can do: pass a value to a function, and 
have the function mutate that value. If the mutation appears in the 
caller's environment, then the value wasn't copied and it is not call-by-
value. In Python:

def mutate(alist):
alist.append(1)

L = [1, 2]
mutate(L)  # supposedly call by value
assert L == [1, 2]

If the assert statement fails (and it does), then no copy was made and 
Python is not call-by-value.

So Python is not call-by-value, and it's not call-by-reference, so ... 
either Python doesn't exist, or it uses a different calling convention.


-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-04 Thread Steven D'Aprano
On Tue, 04 Nov 2008 09:06:45 -0700, Joe Strout wrote:

 This example is also call-by-value, but the value in this case is a type
 that has no analog in Python.

I'm disappointed to see that my prediction that Joe would, yet again, 
utterly ignore all the arguments against his pet theory was correct. It's 
gratifying to be proven right, of course, but I'd prefer to be wrong and 
reduce the amount of confusion and obfuscation that Joe is causing.

Over the years, I've had the misfortune to deal with many people like 
Joe. They get a fixed idea in their head, and regardless of the facts 
they will stick to it, no matter what: when the facts disprove your pet 
theory, ignore the facts.

When we're talking about the value of a variable in Python, why on earth 
would you drag entities that do not exist in Python into the discussion? 
That is too low a level. It's analogous to my earlier tongue-in-cheek 
suggestion that all languages are in fact call-by-bit-flipping: 
technically true at some level of explanation, but not at the level of 
the Python virtual machine.



-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the instance reference of an object

2008-11-04 Thread Steven D'Aprano
On Tue, 04 Nov 2008 09:16:05 -0800, Craig Allen wrote:

 When you consider the status of the entity x in x=1 in python, it is
 a pointer, and python looks like pass by value.

Nonsense. Python doesn't have pointers. You're letting Joe confuse you. 
Python has objects: *everything* in Python is an object, and you have no 
access to pointers. Everything else is an implementation detail, and that 
is subject to change between implementations.


 The need for a different name comes from the fact that using pointers
 ubiquitously like this leads to behavior much more like pass by
 reference.

And the confusion strikes again... you've just said that Python looks 
like pass by value, and now you say that Python's behaviour is much 
more like pass by reference. Can you not see that this is a 
contradiction?


 I'm open to pass-by-sharing, or pass-by-object, but neither is
 perticularly intuitive, not as obvious in meaning as pass-by-val or
 pass-by-reference (or call-by-xxx).

There's nothing intuitive about call-by-reference or call-by-value 
either, they are modes of behaviour that need to be learned. And even if 
we accept that somehow people are born with in inherent knowledge of how 
C++ passes function parameters, that certainly doesn't apply to what Joe 
is peddling: that the value of a variable is an arbitrary and hidden 
reference to the actual value you want.


 I suppose I'd like pass-by-name as
 more a description, as name to me has a similar sense to pointer, at
 least in a language that preserves the name as a runtime entitity
 (making C/C++ languages which compile away names).

Pass-by-name already has a meaning, and it isn't what Python does.

Craig, please ignore all the implementation-specific details of how the C-
implementation of Python works. That's not Python-the-language. 
IronPython works differently, so does Jython, so does PyPy. In fact, 
IronPython exposes to the Python programmer .Net objects where call-by-
reference is actually correct (or so I'm told).

At the level of Python code, Python operates on *objects*. When you call 
a function with an argument, the argument (an object) is NOT copied, it 
is passed to the function. If you mutate the argument inside the 
function, you are changing the object and the caller will see the 
mutation: this is just like call-by-reference, and unlike call-by-value. 
But if you assign a different object to the argument name, the caller 
does NOT see the change, which is just like call-by-value. So depending 
on what type of object the argument is, and depending on what you do 
inside the function, you get something that looks rather like call-by-
value or call-by-reference semantics. But what the Python VM does is the 
same no matter what you do: Python's calling model is different from 
either byval or byref. The accepted name for that calling model is call-
by-sharing, or sometimes call-by-object or even call-by-object-
sharing, and it goes back at least to 1974 and the CLU language, and 
arguably even older than that to Lisp.



-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list


  1   2   3   >