anything like C++ references?

Bengt Richter bokr at oz.net
Tue Jul 15 16:32:30 EDT 2003


On Tue, 15 Jul 2003 02:40:27 +0100, Stephen Horne <intentionally at blank.co.uk> wrote:

>On Mon, 14 Jul 2003 00:07:44 -0700, Erik Max Francis <max at alcyone.com>
>wrote:
>
>>Stephen Horne wrote:
>>
>>> Imagine, for instance, changing all assignments and other 'copying' to
>>> use a copy-on-write system. Then add a pointer type and a 'newcopyof'
>>> operator. And nick the C-style prefix '*' for dereferencing and add
>>> '&' as a 'make a pointer to this object' operator (absolutely NOT a
>>> physical memory address).
>>
>>The problem is that this misses the point that Python is not C++.  You
>>shouldn't try grafting syntaxes and approaches that make Python look
>>more like C++, you should be learning to use Python on its own merits.
>
>Not true.
>
>If you eliminate all violations of the idea of variables bound to
>values (basically the whole point of my thread), then mutable
>containers cannot achieve the same thing.
>
>If a copy-on-write scheme is added to Python, you'd get the following
>results from using mutable containers...
>
>>>> a = [1, 2, 3]
>>>> b = a
>>>> b[2] = 4
>>>> a
>[1, 2, 3]
>>>> b
>[1, 2, 4]
>
Yes, but it would be hugely inefficient for the case where, e.g., you are
modifying lines read from a 20MB log file. Imagine inducing a 20MB copy
every time you wanted to delete or modify a line. Now you have to invent
a way to program around what can be done very conveniently and efficiently
thanks to Python's semantics.

When you actually want a copy, just make one. There is syntax for that:

 >>> a = [1, 2, 3]
 >>> b = a[:]
 >>> b[2] = 4
 >>> a
 [1, 2, 3]
 >>> b
 [1, 2, 4]

>That is, mutability of the list object could be used to conveniently
>and efficiently rebind the variable b (in this case to the value [1,
>2, 4]) but that doesn't implicitly rebind the variable a which has
>nothing to do with this assignment. In the implementation, Python
it's not a variable in your sense, it's an alias.

>would create a copy of the object bound to [1, 2, 3] just in time to
>apply the change that object, without affecting the object that a is
>bound to.
>
>Efficient, and it implements the variable-bound-to-value concept.
Hugely inefficient, whether by brute force copying or by storing
complex everything-but-this-and-with-that-mod dumb-pointer kludges
to try to avoid bulk copying.

>
>Having done this, there would be a need for a way of indirectly
>referencing objects. You wouldn't be able to abuse containers for this
>goal. Pointers are the logical way to achieve the goal of indirect
>referencing - they don't need to be associated with a type of
>container which may have nothing to do with the problem, and they can
>be used to reference *any* type of object.
>
>>Or, to put it another way, if you want to program in C++, why not use
>>C++?
>
>I don't want to program in C++ (though sadly I have to).
>
>The concept of a pointer as an indirect way of referencing an object,
>however, is useful. It isn't just a C++ concept. It is a widely used
>concept from many languages which has gone out of fashion, mainly
>because of the low level detail of how pointers are implemented in
>languages such as C++ (ie simple store addresses).
Ok, and Python makes major use of "indirect way[s] of referencing an object."
Just not quite the way you have in mind ;-)

>
>I don't want the C++ bug-prone implementation of pointers. I want
>something which allows indirect referencing of objects in a logical
>and safe, high level way - and something which doesn't require the
>language to break the principle of variables bound to values.
>
Python doesn't break that. Python deals in aliases, not your "variables."

>The fact that pointers are generally useful can be seen in the regular
>abuse of single item lists to fake the functionality of pointers.
>
That is a valid point, but the solution is not wholesale change of semantics
followed by special syntax to allow us to do what we are already doing.

In a past post I suggested using := as an update operator, which would allow
you to write def foo(x): x:=123 and have foo(z) cause z to be updated with 123
-- if it was an updatable object. And updatable objects would have a __update__
method, so that x:=123 would be equivalent to x.__update__(123).
(I called it __update__ rather than e.g. __setval__ because it is not a value
replacement operation in general).

I've also floated the idea of being able to create what might be called bound properties.
I.e., something that looks like a plain x but acts like some_class_instance.x where x is
a property of that class. I.e., when you assign to it, it calls the setter function and
when you use it in an expression it calls the getter function. Something like you can
do (on the read side) with parameterless functions in Pascal (IIRC).

But that is a lot of change to be able to write x instead of o.x ;-)

Hm, if there were a name space where name bindings would work the way you want, would
that make you happy? I.e., where you could write

    ns.a = [1, 2, 3]
    ns.b = ns.a
    ns.b[2] = 4
    ns.a
    ns.b

Here's a start:

 >>> class NSHorne(object):
 ...     from cPickle import dumps, loads
 ...     def __setattr__(self, name, val):
 ...         object.__setattr__(self, name, self.loads(self.dumps(val)))
 ...
 >>> ns = NSHorne()
 >>> ns.a = [1, 2, 3]
 >>> ns.b = ns.a
 >>> ns.b[2] = 4
 >>> ns.a
 [1, 2, 3]
 >>> ns.b
 [1, 2, 4]

>If people are routinely faking the abstraction, maybe that is because
>it is a useful abstraction to have. Maybe it would be better to
>support it explicitly instead of forcing people to use tricks and
>hacks.

Or maybe it can be solved short of creating a whole new language ;-)

Regards,
Bengt Richter




More information about the Python-list mailing list