"always passes by reference"

Tim Peters tim_one at email.msn.com
Tue Jul 25 22:19:55 EDT 2000


[Greg Weeks]
> Once upon a time, "pass by reference" meant that a function call
> f(x) could modify the binding of the variable x.

I suspect you're conflating "once upon a time" with the specific languages
you just happened to be using back then.  Calling conventions have *always*
been a zoo in reality, and all terms used to describe them are heavily
overloaded.  They usually make sense only in the context of a specific
language.

> With this definition, "pass by reference" effectively passes the
> address of the variable x to the function.  "pass by value", by contrast,
> passes only the value of the variable x, not its address.
>
> With these definitions, Python is uniformly "pass by value".
> So are Lisp, Java, and C, but not C++ and Perl.

I don't agree with any of that, but in the absence of much more careful
definitions this isn't going to get anywhere.

> I like these old definitions.  Unfortunately, things now get
> confusing when the value of a variable is an address.  This wasn't
> always the case.  In the Lisp and Smalltalk communities back in the
> early 80's (as I recall), it was generally understood that an
> interesting mutable data type (such as a list) is implemented
> internally as an address.  The address isn't a "reference" to a
> list.  The address IS the list.  But now it seems that under the
> influence of C and especially C++, the notion that an address can
> represent a thing (such as a list) is entirely out of favor.  Oh,
> well.

Languages that expose implementation accidents (like addresses) have a real
need to make this distinction.  Python, happily, does not.

> I prefer the old way of speaking.

I suspect I've been around even longer than you <wink>, and there was no
"the" old way of speaking:  just as now, there where many ways of speaking
about calling conventions, and some languages (e.g., Fortran) allowed many
ways of implementing their visible calling semantics (e.g., Fortran is what
you'd probably call a "call by reference" language based on its semantics,
but many implementations actually passed copies of scalar values, then
copied alterations of those copies back into the caller's memory locations
upon return -- in the Fortran implementation world, this went by the name of
"call by value/result").

> With the new way of speaking, both Python and Perl are "pass by
> reference", but Perl is somehow *more* so.

Perl is much more call by value, even in the venerable old Pascal sense.
For example, if you pass a list in Perl, Perl passes (the address of) a
physical copy of the list (much as Pascal made physical copies of non-var
array arguments).  It wasn't until Perl 5 that you could even ask for a
reference in Perl.  Python passes (the address of) the actual list, and
"list" can be replaced by any Python type whatsoever; all Python arguments
are treated exactly the same way.

> That's confusing.

That may be self-inflicted, you know <wink>.  Seriously, implementations are
subtle and varied.

> And in the new way of speaking, in Python you don't pass numbers,
> lists, and so on to functions.  You have to say that you pass
> "references" to these things.  But when you're in a hurry, you skip
> this "references" business and talk about passing numbers, lists,
> and so on.  This hasty way of speaking used to be considered correct,
> and I still like it.

By all means, use it!  You won't find Python experts talking about "passing
references" unless they're speaking to hardcore C or C++ people who can't
think in any other terms.  I *never* think of call semantics in Python that
way.  A semi-accepted term to describe what Python (and similar languages)
do is "call by object".  Anyone thinking about references under the covers
is just confusing their mental picture -- only the implementers have to
worry about that, and even then rarely.

it's-not-easy-to-be-simple-ly y'rs  - tim






More information about the Python-list mailing list