Pass-by-reference : Could a C#-like approach work in Python?
mcherm at mcherm.com
Thu Sep 11 19:22:22 CEST 2003
First, thanks to Stephen Horne for bringing up this subject. I learn
more about language design in this newsgroup than anywhere else
(perhaps people who appreciate good language design gravitate to
I started by looking for use cases... where would this proposed
pass-by-reference actually prove useful? Stephen basically found
one good use case:
I wish to "transfer ownership" of an object that gets passed
into a method call, and protect against the caller accidently
continuing to use the object. [So, we'll use a "ref" parameter and
set the caller's variable to None.]
But "pass by reference" isn't the first idea I have on reading the
use case. I agree with Peter Otten, who writes:
> if copying is costly and only
> sometimes necessary, wrap the item into a copy-on-write proxy for every
> logically distinct but physically identical instance.
Excellent idea! But, how do I write a copy-on-write proxy in Python?
Seems like this would make an excellent cookbook recipie, but I couldn't
figure out how to do it. Proxying is easy, but how does one distinguish
between mutating and non-mutating methods? Does the proxy need to be
customized for each class to be wrapped?
Also I wanted to mention what _I_ saw as the major reason why including
reference parameters in Python would be a bad idea. Stephen himself
pointed out that without compelling use cases, YAGNI should rule. But
the counter argument of "it will allow unexpected changes whenever I
invoke a method" is completely bogus -- from the beginning Stephen
pointed out that special syntax should be required BY THE CALLER. And
the counter argument of "it will slow things down" is dubious at best
(cPython method calls are already so slow that it's unclear how much
difference this would make).
But my counter argument would be that this breaks one of the elegent
simplicities of Python -- that callables of all kinds are equivalent
and have a very simple interface. A callable receives (in effect)
one tuple of values, and one map of values. That's it. That's a very
simple protocol. Functions and methods are written with a bunch of
ordered, named parameters, (some of which may have defaults), that
are filled in from this tuple and map, and perhaps an overflow tuple
and map for additional inputs. There's no place in this simple
protocol for type declarations (of course), and there would be no
place for tracking whether an argument was "ref" or not. To add even
that one boolean property would significantly complicate callables.
I think that having a small number of protocols that are very simple
yet very powerful is a wonderful way to design a language. Python's
callables are very simple, yet powerful. Iterators are another such
example. Making classes consist primarily of a namespace (__dict__)
was another, although that has gotten much more complicated as
things like descriptors are introduced.
Anyway, just wanted to share some thoughts you had triggered. Thanks
for the ideas.
-- Michael Chermside
More information about the Python-list