Finding the instance reference of an object

D

Dale Roberts

...

It's been a LONG time since I did anything in C, but yes, I believe  
that reference parameters were an addition that came with C++.

Okay, I completely understand you, and I think we will just have to
agree to disagree about the best term to use for Python's parameter
passing mechanism, and this will likely be my concluding post on this
topic (although I have enjoyed it very much and have solidified my own
understanding).

I even found a few web sites that very strongly support your viewpoint
(as it relates to Java):

http://www.ibm.com/developerworks/library/j-praxis/pr1.html
http://javadude.com/articles/passbyvalue.htm
http://www.yoda.arachsys.com/java/passing.html

The difference is that I would say that C supports the Pass By
Reference idiom using this syntax:

myfunc(int *val){} /*CALL:*/ myfunc(&i);

which actually passes an address expression (not a variable) by value,
but "looks and feels" like a reference to the "i" variable, which
contains the real value that we care about - and allows modification
of that value.

C++ adds a syntactic change for this very commonly used C idiom, but
does not add any new capability - the results are absolutely
indistinguishable.

Python, likewise, in relation to the values we care about (the values
contained only in objects, never in variables) behaves like Call by
Object Reference.

If I tell someone that Python uses only Call By Value (and that is all
I tell them), they may come away with the impression that variables
contain the values they care about, and/or that the contents of
objects are copied, neither of which is the case, even for so-called
"simple", immutable objects (indeed, at the start of this thread, you
said you believed that, like Java, simple values were contained within
Python variables).

But Python, unlike Java or most other commonly used languages, can
ONLY EVER pass an object reference, and never an actual value I care
about, and I think that idiom deserves a different name which
distinguishes it from the commonly accepted notion of Pass By Value.

Thanks for a thoughtful discussion,
dale
 
D

Dale Roberts

... that idiom deserves a different name which
distinguishes it from the commonly accepted notion of Pass By Value.

Bah, what I meant to end with was:

Just as the Pass By Reference idiom deserves a unique name to
distinguish it from Pass By Value (even though it is often Pass By
(address) Value internally), so Pass By Object Reference deserves a
unique name (even though it too is Pass By (reference) Value
internally).

Again, thanks for the discussion,
dale
 
G

greg

Douglas said:
Because there's an important distinction to be made,

The distinction isn't about parameter passing, though, it's
about the semantics of *assignment*. Once you understand
how assigment works in Python, all you need to know then
is that parameters are passed by assigning the actual
parameter to the formal parameter. All else follows from
that.

This holds for *all* languages that I know about, both
static and dynamic. Once you know how assignment works in
the language concerned, then you know how parameter
passing works as well. There is no need for new terms.
and the
distinction has been written up in the Computer Science literature
since Lisp first starting using the same argument passing semantics as
Python back in 1958. The semantics are called "call by sharing".

I still think it's an unnecessary term, resulting from
confusion on the part of the authors about the meanings of
the existing terms.

If there's any need for a new term, it would be "assignment
by sharing". Although there's already a term in use for that,
too -- it's known as reference assignment.
Many mainstream programming languages other than Python now use call
by sharing. They include Java, JavaScript, Ruby, ActionScript, and C#.

I would say they use assignment by sharing, and call by
value.
 
G

greg

Gabriel said:
En Tue, 28 Oct 2008 00:58:10 -0200, greg <[email protected]>
escribió:
>

Those definitions are only applicable to unstructured, primitive types,
where the only relevant operations are "get value" and "assign value".
Structured types provide other operations too - like selection
(attribute get/set in Python).

But that isn't what "assigning to the formal parameter" means --
it only means assigning directly to the parameter *name*.
It is unspecified on both definitions
above what happens in those cases.

That's true, but it's outside the scope of the parameter passing
mechanism to define what happens in those cases. That's down to
the data model being used by the language and the semantics of
assignment in general.
 
G

greg

Dale said:
Okay, you can have it that way, but every time you explain to someone
that Python passes "By Value", you will have to add the additional
baggage that, oh, by the way, there is a completely different meaning
for "value" in Python than what you are used to.

For what it's worth, I happen to agree that telling
someone that Python passes parameters "by value" without
being sure they understand exactly what "by value"
means, is not a good idea -- not because the term
isn't well-defined, but because of the widespread
confusion out there about it.

But equally I wouldn't tell someone that it's *not*
by value, because if they do happen to correctly
understand what it means, that will confuse them just
as much.

So my recommendation is just to tell them that it
works by assigning the result of evaluating the actual
parameter to the formal parameter.

If they understand how assignment works in Python, that
tells them all they need to know.

If they don't understand how assignment works, then they
have a more fundamental knowledge gap that needs to be
corrected first.
 
S

Steven D'Aprano

Python's behavior is exactly and always equivalent to the "ByVal"
behavior of languages that have both behaviors.

Pascal has both ByVal and By Ref, and Python's behaviour is absolutely
not the same as Pascal's ByVal.
It also matches the definition of call-by-value.

Which definition of call-by-value? Certainly not the one that most people
are familiar with, where c-b-v implies that calling a function with a
large array will copy the entire array.

I quite agree that it's not helpful to
delve into the physical flipping of transistor states.

Nor is it helpful to delve into the implementation details of pointers
and references. There are no such things in Python code, and the Python
virtual machine doesn't see them. Only the underlying implementation sees
them, and as Fuzzyman has already explained, the .Net implementation of
IronPython differs from the C implementation of CPython, and this has
real consequences for Python code exposed to .Net objects.

We're talking
about the behavior, and the behavior, very clearly, is call-by-value.

Only if you redefine c-b-v to something that it unrecognizable to anyone
else.

Joe, you've got a cheek sneering at us for inventing new terms (that we
didn't in fact invent, that have a long history in the IT field, one
involving such giants as Barbara Liskov) when your entire argument rests
on the hijacking of the word "value" to mean "some arbitrary,
implementation-dependent reference to the thing which is the actual
value".

It is an abuse of language and common sense to claim that after executing
x=42, the "value" of x is 149605700 (or whatever arbitrary memory
location you happen to get). That nonsensical idea is the bedrock of your
entire argument.
 
S

Steven D'Aprano

For what it's worth, I happen to agree that telling someone that Python
passes parameters "by value" without being sure they understand exactly
what "by value" means,

"By value" is very simple. It means a copy of the value is passed to the
function.

Using "call by value" to mean "pass a copy of a reference to the value"
is an abuse of terminology, because that's exactly what happens in call
by reference: a copy of the reference to the value is passed.

is not a good idea -- not because the term isn't
well-defined, but because of the widespread confusion out there about
it.

Well duh. All these people trying to insist that after executing x=1 the
value of x is some arbitrary memory location are certainly confused.

But equally I wouldn't tell someone that it's *not* by value, because if
they do happen to correctly understand what it means, that will confuse
them just as much.

But it isn't call by value. Why wouldn't you tell people it is when the
value isn't being copied?


So my recommendation is just to tell them that it works by assigning the
result of evaluating the actual parameter to the formal parameter.

And 99% of them will just say "What?".

That's not an explanation, it's obfuscation at its worst. What *is* the
result of evaluating the actual parameter? Is it a reference to the
object or the object itself? Is it a copy of the object? A shallow copy?
A deep copy? Not a copy at all? What implications for behaviour does it
have? What does it mean?


If they understand how assignment works in Python, that tells them all
they need to know.

Nonsense.
 
A

Aaron Brady

Nonsense.

Maybe I missed this part. What does the phrase, "value of variable x"
mean in Python? Is it the same as what it means in C, Pascal, etc.?

In other words,
'0xb39dd0'

What is the value of 'x'?
a) [ 2, 3, 4 ]
b) An object with contents [ 2, 3, 4 ]
c) 0xb39dd0
d) None of the above.

I hold that the burden of proof is yours if you hold that there is
more than one answer.

If "value of 'x'" is not defined, we should agree on a definition
that's really clear and useful, favoring useful. After that's
established, we can proceed to evaluating what 'call by value' would
behave like, which would then determine if Python behaves like it.

So, logically, if... she... weighs... the same as a duck,... she's
made of wood.
 
J

Joe Strout

The distinction isn't about parameter passing, though, it's
about the semantics of *assignment*. Once you understand
how assigment works in Python, all you need to know then
is that parameters are passed by assigning the actual
parameter to the formal parameter. All else follows from
that.

This holds for *all* languages that I know about, both
static and dynamic.

Just to be complete, it only holds in "ByVal" mode (for languages that
have both ByVal and ByRef modes, like VB.NET). A call-by-value
parameter pass is equivalent to an assignment to the formal parameter,
as you say. A call-by-reference parameter is not.

This is yet another simple way to see what type of parameter passing
Python uses.
Once you know how assignment works in
the language concerned, then you know how parameter
passing works as well. There is no need for new terms.

Agreed.

Best,
- Joe
 
J

Joe Strout

For what it's worth, I happen to agree that telling
someone that Python passes parameters "by value" without
being sure they understand exactly what "by value"
means, is not a good idea -- not because the term
isn't well-defined, but because of the widespread
confusion out there about it.

But equally I wouldn't tell someone that it's *not*
by value, because if they do happen to correctly
understand what it means, that will confuse them just
as much.

So my recommendation is just to tell them that it
works by assigning the result of evaluating the actual
parameter to the formal parameter.

If they understand how assignment works in Python, that
tells them all they need to know.

If they don't understand how assignment works, then they
have a more fundamental knowledge gap that needs to be
corrected first.

That's a very sensible stance. +1!

Best,
- Joe
 
D

Douglas Alan

greg said:
The distinction isn't about parameter passing, though, it's about
the semantics of *assignment*. Once you understand how assigment
works in Python, all you need to know then is that parameters are
passed by assigning the actual parameter to the formal
parameter. All else follows from that.

This holds for *all* languages that I know about, both
static and dynamic.

Then you don't know about all that many languages. There are
languages that use call-by-name, and those that use
call-by-value-return. Some use call-by-need and others do
call-by-macro-expansion. Etc. These languages generally don't use
these same semantics for assignment.

All languages that I know of that use call-by-sharing also do
assignment-by-sharing. Not all languages that do
assignment-by-sharing always do only call-by-sharing, however. For
instance, most dialects of Lisp have procedural macros. The calling
semantics of procedural macros are quite different from the calling
semantics of normal functions, even though procedural macros are Lisp
functions. Other dialects of Lisp provide the ability to state that
certain function arguments won't be evaluated at call time. All
dialects of Lisp, however, do assignment-by-sharing, or "binding" as
it is called in the Lisp community.

Also, one could certainly invent additional languages that do behave
in the typical manners.

If you are merely asserting, however, that understanding how Python
does assignment will help you understand how Python does argument
passing, then you are certainly correct. This, however, does not
imply that there is not a pre-existing precise terminology to describe
Python's calling semantics, and that this term can be useful in
describing how Python works.

If I tell you, for instance, that Java, Python, Ruby, JavaScript,
Lisp, and CLU all use call-by-sharing, then I have said something that
makes a similarity among these languages easier to state and easier to
grasp.
Once you know how assignment works in the language concerned, then
you know how parameter passing works as well. There is no need for
new terms.

This is simply not true.
I still think it's an unnecessary term, resulting from confusion on
the part of the authors about the meanings of the existing terms.

Trust me, Barbara Liskov was not one bit confused when she invented
the term "call-by-sharing". And her language CLU was one of the most
prescient to have ever been designed and implmented.
If there's any need for a new term, it would be "assignment by
sharing". Although there's already a term in use for that, too --
it's known as reference assignment.

Reference assignement doesn't imply that the object is allocated on a
heap, and "call-by-sharing" does.
I would say they use assignment by sharing, and call by value.

We can also argue about how many angels can dance on the head of a
pin, but the term "call-by-sharing" has been around since the 70s, and
it is already well-defined and well understood.

|>oug
 
G

greg

Dale said:
Are you
saying that C++ is capable of using the Call By Reference idiom, but C
is not, because C does not have a reference designation for formal
function parameters?

Call by reference is not an "idiom", it's a *language
feature*.

Pascal has it (using "var"), VB.NET has it (using "ByRef"),
C++ has it (using "&"). C does not have it, because there is
no syntax in the language for it. Neither does Python.

You can use an idiom in C to get the same effect, but this
is not the same thing as the language having it as a feature.
You cannot look a C++ programmer straight in the eye and say that
"Python uses Call By Value, Period", without also informing them that
"Python variables can ONLY EVER hold object references - that is the
only "value" they can ever hold".

But he had darn well better learn that anyway, otherwise he's
going to have massive problems programming in Python that
don't have anything to do with parameter passing!
 
G

greg

Joe said:
(Perhaps explaining why there appears to be far more
confusion about call semantics in the Python community than in the
community of other languages where the default semantics are exactly
the same.)

I think part of the problem stems from the fact that the
word "value" is often used rather loosely in relation to
Python, sometimes to mean a reference to an object and
sometimes to the contents of the object itself. So there's
a tendency to avoid using it when trying to speak
precisely. Some even go so far as to declare that there is
no such thing as a "value" in Python.

Then people see the term "call by value", and have a
fit of apoplexy because it has the forbidden word "value"
in it. How can we apply this term, they say, if we can't
decide what a value is?

The way out is to realise that you don't *have* to assign
any meaning to the term "value" in order to apply the
term "call by value".

If you look at the definitions I posted, you'll notice that
I carefully avoided using the terms "value", "reference",
"variable", "address" or any other such controversial words.

I did use the notion of the "result of evaluating an
expression", but only in the context of assigning it to a
name. Nobody seems to have any qualms talking about that in
Python, as far as I know.

So in summary, just treat the terms "call by value" and
"call by reference" as atomic identifiers, defined in terms
of assignment semantics. Don't try to pick them apart and
understand them in terms of "values" and "references".
 
G

greg

Dale said:
Just as the Pass By Reference idiom deserves a unique name to
distinguish it from Pass By Value (even though it is often Pass By
(address) Value internally), so Pass By Object Reference deserves a
unique name (even though it too is Pass By (reference) Value
internally).

Since Python only has one parameter passing mechanism,
there's no need to give it a name at all. If you're
having to explain it, just explain it, and don't
bother naming it!
 
G

greg

Steven said:
Which definition of call-by-value? Certainly not the one that most people
are familiar with, where c-b-v implies that calling a function with a
large array will copy the entire array.

But that's only true in languages where *assigning* a large
array will also copy the entire array. This does not happen
in Python, therefore there is no reason to suppose that it
will happen when passed as a parameter.

Before you can understand parameter passing, whether by-value
or by-reference, you first have to understand how assignment
works *in the language concerned*, not some other language
you happen to know previously.
 
G

greg

Steven said:
"By value" is very simple. It means a copy of the value is passed to the
function.

It only means that if you understand "copy" to mean
whatever it is that happens when you perform an assignment.
In Python, the term "copy" tends to imply rather more
than that, so you go off the rails using that definition.
That's not an explanation, it's obfuscation at its worst.

I didn't necessarily mean to use those exact words. The
essential point is that you explain parameter passing in
terms of assignment.
What *is* the
result of evaluating the actual parameter? Is it a reference to the
object or the object itself?

It doesn't matter! All that matters is that they understand
what happens when you assign it to a name. You can explain
that using whatever terminology you want, as long as they
end up with a mental model that works. Then you tell them
that passing a parameter is just like doing an assignment.

I can't think what could be simpler or less obfuscatory
than that.
Nonsense.

Why? What else *do* you think they need to know?
 
G

greg

Aaron said:
Maybe I missed this part. What does the phrase, "value of variable x"
mean in Python?

I didn't use the phrase "value of variable x" anywhere in my
definitions, so it doesn't matter what it means, or even
whether it means anything at all.
If "value of 'x'" is not defined, we should agree on a definition
that's really clear and useful, favoring useful. After that's
established, we can proceed to evaluating what 'call by value' would
behave like, which would then determine if Python behaves like it.

There you go, getting distracted by that annoying word
"value". Forget about it, we don't need it!
 
G

greg

Douglas said:
Then you don't know about all that many languages. There are
languages that use call-by-name, and those that use
call-by-value-return. Some use call-by-need and others do
call-by-macro-expansion. Etc.

I didn't mean that these are the only two parameter passing
mechanisms in existence -- I know there are others.

What I mean is that in all languages I know of that have
by-value or by-reference or both, they behave according to
the definitions I gave. If anyone has a counterexample,
I'll be interested to hear about it.
For
instance, most dialects of Lisp have procedural macros. The calling
semantics of procedural macros are quite different from the calling
semantics of normal functions

Yes, but nobody refers to that as either by-value or
by-reference as far as I know. Lisp people would probably
talk about the parameter being passed either "evaluated"
or "unevaluated".
If I tell you, for instance, that Java, Python, Ruby, JavaScript,
Lisp, and CLU all use call-by-sharing, then I have said something that
makes a similarity among these languages easier to state and easier to
grasp.

If you told me they use "assignment by sharing", that would tell me
a lot *more* about the language than just talking about parameter
passing.
 
G

greg

Steven said:
Using "call by value" to mean "pass a copy of a reference to the value"
is an abuse of terminology, because that's exactly what happens in call
by reference: a copy of the reference to the value is passed.

No, it's not a reference to a value, it's a reference to
a *variable* (what C calls an lvalue). There is no such
thing as a reference to an lvalue in Python.

The presence of the word "reference" in "call by
reference" is another nasty terminology collision,
because it has nothing to do with what's called a
"reference" in Python.

The historical choice of terms is somewhat unfortunate.
If they'd been called something like "call by assignment"
and "call by alias", none of this confusion would have
arisen.
 
S

Steven D'Aprano

I think part of the problem stems from the fact that the word "value" is
often used rather loosely in relation to Python, sometimes to mean a
reference to an object and sometimes to the contents of the object
itself. So there's a tendency to avoid using it when trying to speak
precisely. Some even go so far as to declare that there is no such thing
as a "value" in Python.

I think you're imagining that.

Perhaps you are confused by the fact that there are people (including
myself) who try to avoid using the term "assign to a variable" and prefer
to use "bind to a name" instead. But value? Given x=1, what else could
the value of x be other than the object 1?

Then people see the term "call by value", and have a fit of apoplexy
because it has the forbidden word "value" in it. How can we apply this
term, they say, if we can't decide what a value is?

We know what a value is. A value is the thing denoted by a symbol. In the
context of Python, the value of the name x is the object bound to that
name.

The way out is to realise that you don't *have* to assign any meaning to
the term "value" in order to apply the term "call by value".

Call by value already has at least one well-established meaning. It's a
meaning that isn't compatible with what Python does.

In such languages as Pascal and C, a variable such as x refers to a fixed
memory location of a known size. The assignment x = 1 sets the bytes at
that location to the value 1. When you call func(x) the value of x (the
value 1) is copied to another memory location which is local to the
function.

The same holds when x is an array. If x is an array of 1MB, then func(x)
will copy 1MB of bytes into a local variable of func.

[...]
So in summary, just treat the terms "call by value" and "call by
reference" as atomic identifiers, defined in terms of assignment
semantics. Don't try to pick them apart and understand them in terms of
"values" and "references".


In other words, in order for "call by value" to have any meaning in
Python, we have to forget all about the ordinary meaning of the words
"value" and "references" and just treat them as magic words unrelated to
"call by value" in any other language.

Might as well call it "call by milk" or "call by fjH?agx" instead.
 

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
473,781
Messages
2,569,616
Members
45,306
Latest member
TeddyWeath

Latest Threads

Top