Finding the instance reference of an object

M

Marc 'BlackJack' Rintsch

That's in the "no fair" category. C can do a swap operation on mutable
types, too, though it also has only pass-by-value. Same for Java, or
for REALbasic or VB.NET using "ByVal" mode. The fact that you can
mutate mutable types has absolutely nothing to do with whether the
parameter was passed by reference or value. If was by reference, you
can change it (the parameter itself, not something the parameter may
refer to). If it's by value, you can't.

In Python, you can't. That's because parameters are passed by value.

This conclusion is flawed because call-by-value is not the only parameter
passing style with that characteristics.
True, but the others are rarely used and don't apply to any of the
languages we've been discussing.

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

Ciao,
Marc 'BlackJack' Rintsch
 
S

Steven D'Aprano

True, but the others are rarely used and don't apply to any of the
languages we've been discussing.

Yeah, uncommon, rare languages that nobody uses, like Java, Lisp and
Python.
 
J

Joe Strout

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/>
 
A

Aaron Brady

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/>

Here is the link to Barbara Liskov's paper, 1992, linked on
effbot.org.

"...arguments are passed "by object"; the (pointer to the) object
resulting
from evaluating the actual argument expression is assigned to the
formal."

http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TR-561.pdf

However a Google search for "call by object", in quotes, returns
mostly Python-related links, which I find somewhat suspicious.

The search for call by sharing was more successful:

" 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.... if a routine assigns an object to a formal argument
variable, there is no effect on the caller."

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

That's an accurate description of Python. If VB.NET does the same
thing, I'll just assume that the designers named their keyword "ByVal"
instead of "ByShare", either to accommodate immutable primitives
(numbers), or to keep the keyword short.
 
S

Steven D'Aprano

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

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?
 
M

Mel

Craig said:
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:5
# Case 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?
 
J

Joe Strout

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
 
B

Bruno Desthuilliers

Joe Strout a écrit :
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.
 
C

Craig Allen

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
 
M

Marc 'BlackJack' Rintsch

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
 
H

Hendrik van Rooyen

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
 
S

Steven D'Aprano

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

Steven D'Aprano

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

Joe Strout

I'm disappointed to see that my prediction that Joe would, yet again,
utterly ignore all the arguments against his pet theory was correct.

I'm not doing that, but the folks on the other side are. (Well, I
don't know if you are in particular, as I've been deleting your
messages to save my blood pressure... this one caught my eye though,
alas.)

For example: we have arguments that you can "modify" a parameter
passed to a function in Python. These ignore the fact that you can
only use (dereference) that parameter to modify something else, no
different from a pointer passed by-value in C/C++. And, when a very
simple test for by-reference is brought up (i.e. writing a Swap
method), this gets ignored again and again, by the otherwise perfectly
nice fellow I've been discussing this with privately for days. There
are many other examples.

It boils down to this: Python's behavior is demonstrably the same as
any other modern OOP language, INCLUDING those that have both by-
reference and by-value parameter modes, except that in Python (as well
as Java), only the by-value mode is available.

This is easily shown, and I've done exactly that at <http://www.strout.net/info/coding/valref/

But I predict that you'll ignore all this evidence that goes against
your pet theory, and continue to cause confusion and obfuscation on
the topic.
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?

I don't, but others do, for example bringing up C structs or C++
objects on the stack, which don't exist in Python (Python objects live
on the heap, and all you have on the stack are references to them; the
proper C/C++ analogy is an object created with "new" and referenced
entirely via pointers).
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.

I agree that we don't need to talk about bits. But we do need to
understand whether code such as:

a = SomeClass()
b = a

creates two objects, or merely two references to the same object.
Once we know whether we're dealing with values or references, then
everything else becomes simple and clear, no matter what language
we're building in.

I know you really want Python to be unique and special -- and it is,
in many ways, but this isn't one of them. Python is an OOP language
whose variables contain references to objects, and where such
references are passed (by value) to methods, just like Java, and like
the default parameter mode in VB.NET, REALbasic, and C++ (though those
languages also offer a by-reference mode that Python and Java do not).

Your continued attempts to obfuscate this simple behavior does no
credit to you or Python.

Best,
- Joe
 
J

Joe Strout

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.

And here is the key bit that you are missing.

When you pass a reference to an object to a function, and then mutate
the object, then OF COURSE the caller (as well as any other holders of
a reference to that object) will see the mutation. This is true in
ANY language. Pick your language, and I will demonstrate it. Here
are a few to get us started (assume a class "Person" with an attribute
"zipcode"):

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

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

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

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


So please clarify your position by identifying which statement applies:

1. You don't believe that these languages are actually passing by value.
2. You don't believe these examples are mutating an object.
3. You don't believe these mutations can be seen by the caller after
the call.
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.

I hate being confrontational, but you're the one accusing me of
ignoring evidence against my "pet theory" (by which you mean the
standard definitions of c-b-v and c-b-r). Let's see what you do with
this evidence that directly contradicts yours.

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

This at least you have correct.
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 no, you don't, as I just demonstrated above (and explained a week
ago at <http://www.strout.net/info/coding/valref/>). You always have
call-by-value semantics. The semantics are exactly the same as in any
other language with anything resembling an object reference, including
those with both "ByVal" and "ByRef" modes (except that there is no
equivalent to the "ByRef" mode in Python).
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.

No, it's exactly byval. No. Different. In. Any. Way.

Let's tackle it this way: one of the following must be true for your
belief system to prop itself up at all:

1. Python's behavior is different from Java, REALbasic, VB.NET, and C++.
....or...
2. None of those languages mentioned use call-by-value.

In fact both of these statements are false, but we can cut our time
and effort in half if you will just select the one that you believe to
be true, so we can focus on that. Which is it?

Thanks,
- Joe
 
A

Aaron Brady

I don't, but others do, for example bringing up C structs or C++  
objects on the stack, which don't exist in Python (Python objects live  
on the heap, and all you have on the stack are references to them; the  

I actually saw an implementation of Python once that did not have
references-to-objects on its stack. It kept them on the heap, and
kept references to those containers in another container. The second
container was a global variable, so that was on the stack at least.
This strongly seems to interfere with your analogy to C++'s c-b-v
mode.

On the other hand, you could say that VB.NET's c-b-v mode is not true
to C++'s c-b-v mode, in which case lots of people will just side with C
++.
 
M

Marc 'BlackJack' Rintsch

I'm not doing that, but the folks on the other side are. (Well, I don't
know if you are in particular, as I've been deleting your messages to
save my blood pressure... this one caught my eye though, alas.)

Yeah, we are all wrong and you are right. Because you say so and ignore
messages that might have facts that are not good for your blood
pressure. Very convincing.
For example: we have arguments that you can "modify" a parameter passed
to a function in Python. These ignore the fact that you can only use
(dereference) that parameter to modify something else, no different from
a pointer passed by-value in C/C++.

But we have no pointers in Python. "Pointer" is a data type in C and C++
but Python, the language, has no such type.
It boils down to this: Python's behavior is demonstrably the same as any
other modern OOP language, INCLUDING those that have both by- reference
and by-value parameter modes, except that in Python (as well as Java),
only the by-value mode is available.

Guess what, I find call-by-value in Java for objects the wrong term too.
Same reason: Java has no pointer or reference as data type.
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?

I don't, but others do, […]

You have said the value that is copied is a pointer to the object. So
the value in your call-by-value is something that doesn't exist in the
Python language.
I know you really want Python to be unique and special -- and it is, in
many ways, but this isn't one of them. Python is an OOP language whose
variables contain references to objects, and where such references are
passed (by value) to methods, just like Java, and like the default
parameter mode in VB.NET, REALbasic, and C++ (though those languages
also offer a by-reference mode that Python and Java do not).

That's just because you seem to insist that a "variable" is a name for a
memory location. A variable brings together name, type, memory location,
and a value, and in Python type and memory location are attached to the
value and not the name, like in C++ for example.
Your continued attempts to obfuscate this simple behavior does no credit
to you or Python.

I think explaining that the object is shared, or given another name
locally, is much simpler than to explain the underlying machinery two
levels below (because the CPython-VM doesn't know pointers either).
Maybe not for people who know that low levels from older languages and
insist on explaining everything in the terms of those. Maybe that's the
reason for the Java folks to call their strategy call-by-value, because
they were afraid to confuse C++ programmers with "new" concepts.

Ciao,
Marc 'BlackJack' Rintsch
 
G

George Sakkis

I know you really want Python to be unique and special -- and it is,  
in many ways, but this isn't one of them.  Python is an OOP language  
whose variables contain references to objects, and where such  
references are passed (by value) to methods, just likeJava, and like  
the default parameter mode in VB.NET, REALbasic, and C++ (though those  
languages also offer a by-reference mode that Python andJavado not).

To Steve's defense, he doesn't claim that Python is special; in one
reply he also disputed the claim that even Java is call-by-value. Of
course most Java programmers would have a hard time taking this claim
seriously, but at least you both agree that Python and Java have the
same call semantics, you just disagree on the name. Googling for 'java
"call by sharing"' brings back only a few results with almost half of
them being Python-related discussions. Steve is definitely in the
minority but he's not completely alone: from
http://www.cs.princeton.edu/courses/archive/fall98/cs441/Lectures/Lec15/Lec15.html:

"""
Like most pure object-oriented languages, Java only supports by "call-
by-sharing". At the implementation level, this is the same as call-by-
value. I.e., the actual parameter value is copied into the formal
parameter before executing the body. At the end of the execution of
the body, the formal parameter just goes away - no copy back occurs. I
prefer to describe it as call-by-sharing because, while you may not
replace the value via an assignment in the method body, you may change
the state of an object value. In particular, if a parameter evaluates
to an object, one can send messages to it which can change its state.
"""

I believe the main source of confusion is wrt C/C++. The following
definition has different semantics in C++ and Java, although they are
both considered call by value:

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

In C++ a Person object itself is copied while in Java (and Python)
only the reference ("handler") is copied. By the way, passing a
(copied) reference is *not* equivalent to call by reference: in the
former case, the assignment of the reference to a different object has
only a local effect, i.e. it is not reflected to the caller's frame,
whine in call by ref it does.

George
 
S

Steven D'Aprano

To Steve's defense, he doesn't claim that Python is special; in one
reply he also disputed the claim that even Java is call-by-value.


Python is as special as CLU, Lisp, Emerald, Iota and others.


"As in Java, the calling semantics are call-by-sharing: the formal
argument variable and the actual argument share the same value, at least
until the argument variable is assigned to. Assignments to the argument
variable do not affect the value passed; however, if the value passed was
an array, assignments to elements of that array will be visible from the
calling context as well, since it shares the same array object."

http://www.cs.cornell.edu/courses/cs412/2001sp/iota/iota.html

Of
course most Java programmers would have a hard time taking this claim
seriously,

That's their problem, not mine. If the Java community wishes to redefine
"value" to mean an arbitrary, implementation-dependent reference instead
of the actual value of the variable, that's their loss.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,434
Messages
2,571,685
Members
48,796
Latest member
Greg L.

Latest Threads

Top