Pass-by-reference : Could a C#-like approach work in Python?

Bengt Richter bokr at oz.net
Thu Sep 11 13:26:39 EDT 2003


On Wed, 10 Sep 2003 14:59:43 +0100, Stephen Horne <$$$$$$$$$$$$$$$$$@$$$$$$$$$$$$$$$$$$$$.co.uk> wrote:

>
>I have in the past suggested that Python functions could use some kind
>of modifier token for parameters to indicate pass-by-reference, so
>that immutable items in particular could be modified (or more
>accurately replaced) by the function, with that modification affecting
>what the caller sees. In case I'm explaining this badly, here is how
>Python currently works...
>
>>>> def Inc(p) :
>...   p += 1
>...
>>>> x = 1
>>>> Inc(x)
>>>> x
>1
>
>... and here is (roughly) what I'd like to be able to do...
>
>>>> def Inc(ref p) :
>...   p += 1
>...
>>>> x = 1
>>>> Inc(x)
>>>> x
>2

ref p logically implies that Inc will receive somehow both the information
*behind* the name 'p' -- i.e., the caller's name for the value that the local
parameter name 'p' is temporarily bound to -- *and* the specific namespace of the caller.

The implication is that there is a name that should be unchanged, whatever it is, but
rebound in its namespace to an updated value. We can't mess with the actual value at
the other end of the binding, since that could be shared and/or immutable.

You could do this very explicitly, e.g., explicitly pass both name space and name string,
with an ordinary dict playing the namespace role:

 >>> ns = {'x':1}
 >>> ns['x']
 1
 >>> def incr(namespace, name):
 ...     namespace[name] += 1
 ...
 >>> incr(ns, 'x')
 >>> ns['x']
 2

or, using the __dict__ of an object instance

 >>> ns2 = type('',(),{})()
 >>> ns2.y = 10
 >>> incr(ns2.__dict__, 'y')
 >>> ns2.y
 11

obviously, we could write incr to accept an instance and a name and do
inst.__dict__[name]+=1 instead of nsdict[name]+=1, but the point is
we are somehow being explicit in specifying both namespace and
the name to be rebound. Implementing ref would imply automating
something similar hidden in the compiled code, IWT. But it gets
messy fast, I think. what if you write a =['foo',[23]]; Inc(a[1][0]) ?
Should that 23 be rebound to a 24? You can't always analyze the expression
statically, so you can't even presume that Inc will be the same global binding
by the time a[1] has been evaluated. So you'd have to look ahead to see if Inc
should be passed the address of the hidden pointer to 0 involved in the [0] or
the pointer to 0 itself. But then you'd have to figure out whether <whatever-a[1]-is>[0]
can be used that way. Should any mutable object that supports __getitem__ and __setitem__
be able to produce the target address for its __setitem__ for conditional passing
to a function like Inc? ISTM a ref thing would ripple pretty far into the binding
methodology of Python.

Regards,
Bengt Richter




More information about the Python-list mailing list