passing by refference

Doug Quale quale1 at charter.net
Thu May 15 19:40:25 EDT 2003


Brian Quinlan <brian at sweetapp.com> writes:

> The real question is, without thinking about implementation, what call
> type best describes Python method calls? One of my CS textbooks has the
> following definition:
> 
> 	"""(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 certainly does not explain the behavior of Python calls.

Your CS textbook is wrong -- what is the name of the book?

Very precise definition of call-by-value would require denotational
semantics (Stoy, Reynolds, etc.) which is out of my league.
Fortunately this idea really isn't that hard so we can take a more
informal view.

"Compilers: Principles, Techniques and Tools" by Aho, Sethi and Ullman

"Call-by-Value

This is, in a sense, the simplest possible method of passing
parameters.  The actual parameters are evaluated and their r-values
are passed to the called procedure.  Call-by-value is used in C, and
Pascal parameters are usually passed this way."

Call-by-value isn't about implementation, it's about behavior.  It
explains the behavior of Python calls.  If you think that it doesn't,
then demonstrate a Python function call that doesn't get passed the
r-values of its parameters.

In Tim Peter's example,

>>> def f(x):
>>>     x[:] = [-1] * 3
>>> 
>>> y = [1, 2, 3]
>>> id(y)
135448932
>>> f(y)
>>> y
[-1, -1, -1]
>>> id(y)
135448932

the variable (name) y is bound to a list object.  List objects are
mutable in Python.  During the call f(y), the local name x is bound to
the same object as y.  After the call f(y), the name y is still bound
to the *same* object.  The call f(y) mutated that object, but y's
binding has *not* changed.  This in itself doesn't make Python
call-by-value, but it doesn't rule out c-b-v either.  C arrays behave
in exactly the same way and C is c-b-v.  In order to apply the
definition of c-b-v to Python we need to know what Python r-values
are.  The r-value is used when you assign directly:

>>> y = [1, 2, 3]
>>> id(y)
135448932
>>> x = y
>>> id(x)
135448932
>>> x[:] = [-1] * 3
>>> y
[-1, -1, -1]
>>> id(x)
135448932
>>> id(y)
135448932

Same behavior.  You can see that Python functions are passed r-values
(the values used for the right sides of assignments).  Other calling
mechanisms such as call-by-reference, call-by-name and
call-by-copy-in-out do not behave this way.

The Pythonistas' meme about what call-by-value is would indicate that
C and Java are not call-by-value.  (In fact only pure functional
languages would qualify, and there's already good terminology to
describe them -- "pure functional language".)  This is incorrect, as
can be seen by applying the correct definition of c-b-v.  It seems
that people are making this too complex by thinking that c-b-v means
more than it really does.





More information about the Python-list mailing list