call by reference howto????

C

castironpi

In that case I find it very strange that when this question comes
up, I see so few attempts to explain how the assignment acctually
works.

        I'll probably get burned for this... but as far as I'm concerned,
assignment works very simply... At the very bottom of the name
resolution, assignment works by changing the left-hand-side "reference"
from any prior object for whatever object represents the result of the
right-hand-side.

        A bare LHS name is rebound in total.
                lhs_name = rhs_expresssion

        A qualified LHS name (a name followed by a ".subname", or a
"[index]", or a "[keyvalue]") rebinds the specified subcomponent of
"name" -- that is, "name" remains bound to some object, and the
".subname" (or "[index]" or "[keyvalue]") component of that object is
what is rebound to the RHS object.
                lhs_name.subcomponent = rhs_expression
                lhs_name[index] = rhs_expression
                lhs_name[keyvalue] = rhs_expression

        No matter how many "." or "[]" sets appear, at the very bottom one
has focused down to a component, and that component get rebound from one
object to another object.

        In no case does the object originally bound get changed. FOR
assignment... Mutables using methods are a bit different...

        lhs.append(rhs)         #assume a list

adds a new element into the list, but it is still the same "list" (and
in that aspect, it is also a "qualified name").

You could warn if a name is assigned to twice-- maybe even error.
Assignment is not a method.

a= object()
a= object()

a is a name. it is a name of an object. what name? a. what
object? that changes on demand.
a= 2
a+= 2
a 4
a= (2,)
a+= (3,)
a (2, 3)
a= 2
id( a ) # 1 505252512
a+= 2
id( a ) 505252544 # !=
a 4
a= (2,)
id( a ) # 2 11863472
a+= (3,)
id( a ) # != 11933976
a= [2]
id(a) # 3 11935296
a+= [3]
id(a) # == 11935296

+= changed the id of a in the first two cases. It did not in the
third. Assignment is not a method. Sometimes augmented assignment
is. In the first two cases, the original was destroyed. In the
third, the newcomer was destroyed. The newcomer was also destroyed in
the first two.

If you can write 'a' on an envelope and it goes to 244 White St., then
assigning to a is an order to the post office: send 'a' to somewhere
else. It doesn't change what it referred to before, though-- those
letters are already delivered!

There is ambiguity in 'change "a"'-- it can mean 'at the post office'
or 'wherever letters address to "a" go to'. However, you can't change
the entry of "a" with the post office of another scope.
"I want 'a' to be [3]." AmbiguityError: Use 'rearrange' or 'reroute'.
"Rearrange 'a'. Move out and move 3 in." a[:]= [3]
"Reroute 'a'. Move 3 in to the place wither mail to 'a' will go."
a= [3]

Some buildings have no entries at the post office. Some names don't
either. You can change the contents of a building if you can send
mail to it-- send a letter that says to change the contents! Other
post offices keep their entries.
Ok!
 
S

sturlamolden

Python doesn't do call by reference. Nor does it do call by value. Please
pay no attention to anyone who says it does.

Exactly. Python pass variables the same way as Lisp, which is neither
"call-by-value" (cf. C) nor "call-by-reference" (cf. Fortran).

The Python equivalent of "pass by reference" is a function that
returns its arguments to the caller:

def foobar(arg1, arg2, arg3):

# Mutate a shared object.
# I.e. calling convention cannot be not "pass-by-value"
arg1.whatever = 1

# Rebind in the local namespace.
# I.e. calling convention cannot be "pass-by-value"
arg1, arg2, arg3 = 1, 2, 3

# Return rebound variables to achieve the effect of
# "pass-by-reference":
return (arg1, arg2, arg3)


# Call the function foobar, and rebind its arguments to its
# return values:

arg1, arg2, arg3 = foobar(arg1, arg2, arg3)
 
S

sturlamolden

Python doesn't do call by reference. Nor does it do call by value. Please
pay no attention to anyone who says it does.

Exactly. Python pass variables the same way as Lisp, which is neither
"call-by-value" (cf. C) nor "call-by-reference" (cf. Fortran).

The Python equivalent of "pass by reference" is a function that
returns its arguments to the caller:

def foobar(arg1, arg2, arg3):

# Mutate an object shared with the caller.
# I.e. calling convention cannot be not "pass-by-value"
arg1.whatever = 1

# Rebind variables in the local namespace.
# I.e. calling convention cannot be "pass-by-reference"
arg1, arg2, arg3 = 1, 2, 3

# Return rebound variables to achieve the effect of
# "pass-by-reference":
return (arg1, arg2, arg3)

# Call the function foobar, and rebind its arguments to its
# return values:

arg1, arg2, arg3 = foobar(arg1, arg2, arg3)
 
S

sturlamolden

Whatever python has for a calling convention, it is close enough that
naming it "call by reference" gives people a reasonable idea of what
is going on.

Only to the extent that many mistake passing Java or C# reference
types for "call-by-reference".

"Call by reference" is the calling convention used by Fortran, Pascal
and Visual Basic 6. If you don't know any of these languages, chances
are you don't understand what "call by reference" really means.
 
D

Dennis Lee Bieber

+= changed the id of a in the first two cases. It did not in the

Small integers are cached in Python, so they always have a fixed ID
(address).
third. Assignment is not a method. Sometimes augmented assignment

Playing with lists, or whatever, as in you example, could mean that
when the reference to the first object was "detached", it was garbage
collected, and the second object could have been assigned the same ID
(address).
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
S

Steven D'Aprano

Small integers are cached in Python, so they always have a fixed ID
(address).

Small integers are cached in CPython, making it an implementation-
dependent feature. I don't believe that caching is promised by the
language definition, and while CPython has a special relationship to
Python-the-language, I don't think an implementation that failed to cache
small integers would be described as "not Python".
 
T

Terry Reedy

| On Sat, 15 Mar 2008 11:50:17 -0700, Dennis Lee Bieber wrote:
|
| > Small integers are cached in Python, so they always have a fixed ID
| > (address).
|
| Small integers are cached in CPython, making it an implementation-
| dependent feature.

Indeed, the set cached has changed from version to version.

| I don't believe that caching is promised by the
| language definition,

No, could even disappear from cPython.
 

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,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top