Augmented assignment again

Roeland Rengelink r.b.rigilink at cable.a2000.nl
Mon Sep 4 05:03:29 EDT 2000


Thomas Wouters wrote:
> 
> On Wed, Aug 30, 2000 at 11:37:29PM +0200, Roeland Rengelink wrote:
> > Thomas Wouters wrote:
> 
> > > As soon as you mix normal binary operators in there, you will get new
> > > objects.
> 
> > The objective of the exercise was not to completely avoid the creation
> > of new objects, just the superfluous creation. I.e. can we implement
> > __add__(self, other) in terms of copies and augmented assignment in such
> > a way that
> >
> > d = a+b+c
> >
> > only results in one copy (of a), and not two (of a and the result of
> > a+b)
> 
> The problem is that Python does not know (and currently cannot know) which
> objects are 'superfluous'.

> The expression 'd = a+b+c' is split into
> "d = ((a+b)+c)", meaning that "a+b" is first calculated (call the result
> 'res'), and then 'res+c' is calculated, and then the result of that is
> stored in 'd'. The "a+b" expression is executed without knowledge of what is
> going to happen with the resulting object (which is precisely the reason why
> something like 'a = a + 1' isn't the same as 'a += 1', in Python 2.0.)
> 

It's somewhat disappointing that my posts didn't show that I was aware
of this :(

>
> Allowing for this kind of optimization *is* possible now that we have
> in-place operations, but it would require substansive rewriting of all of
> the grammar & bytecode-compile-code in current Python. Not something likely
> to happen before Py3K, and probably not even then.
> 

Well, I don't necessarily want/expect Python to do the optimization for
me.
I just brought this up to show that currently it is disappointingly
difficult to do the optimization myself. Note that I _can_ do it (I
think)

To do the optimization myself, I 'only' have to be able to find out if
an object has been bound (Because I can defer the finalize operation to
the next use of the object). I can sort of do this by searching the
entire namespace. The code that I have to do this seems to work.
However, it's currently the third version of the code (up 1 form the
version previously posted) and I don't really know if it correct (And it
won't work with threads).


[snip]

>
> Because it would not be Pythonic ;) It's also bloody hard to see when an
> object is "first bound". 
>

No it isn't. Look for '=' in the source, everything on the right hand
side is being bound. Seriously though. I'm aware that's unPythonic.
That's why I didn't call the original post 'a request for overloaded
assignment' (Though maybe I should have. It would've made the purpose of
the post somewhat clearer).

>
> You can't see it by refcount, because any object
> being stored can be referenced many times, but not actually stored anywhere
> yet. You'd have to keep track of 'boundedness' all of a sudden, for all
> objects in Python. And you need to make some hard decisions on what
> constitutes a 'store' operation. What if you write your own container class,
> which has a '__setitem__' that does *more* calculation on the object ? Would
> you want it to work on the 'finalized' object, or on the 'temporary' one ?
> 

I think the point I'm trying to make is that there are two ways to
optimize

d=a+b+c.

My current implementation relies on a function to detect the boundedness
of an object (1st way). As you point out, this is un-Pythonic, as is
evidenced by the ugliness of the code that does it.

The second way basically requires overloaded assignment.

It's funny that you bring up __setitem__.

As far as I understand assignment, it's close to (but not entirely)
shorthand for

locals().__setitem__('a', b)    # a=b
or
a.__dict__.__setitem__('a', b)    # a.a=b
or
locals().__setitem__('a', [None].__setitem__(0, b)) #a = [b]

(Yes, I'm aware that dicts/lists don't have __setitem__ methods)

It would be handy if '=' was shorthand for

locals().__setitem__('a', getattr(b, '__assign__', lamda x=b: x)())

Or, rather, if a[key] = val, is translated into the somewhat more
complicated

a.__setitem__(key, getattr(b, '__assign__', lamda x=b: x)())

rather than

a.__setitem__(key, val)

Probably still something for Py3K, but not nearly as un-Pythonic as
objects that keep track of their boundedness.

To those who would argue that overloaded assignment is un-Pythonic, one
can counter that we already have the possibility to overload assignement
to indexable types.
(although it's a propertry of the indexable type, not the objects that
are 'assigned' to the index)

> You can 'hack' it by providing your own containers, but it's not a very nice
> solution. I think the explicit act of finalizing, compared with both normal
> binary and in-place operations, and proper education of the programmers
> (because if they write Python, they *are* being programmers) 

Interesting phylosophical question: Do users of Python automatically
become programmers? I think these people would view the Python command
line as the
interface to a data-reduction application of which they are the user.

>should be
> enough to work around this problem. If people refuse to read the
> documentation, they'll pay the price in memory-use. If this isn't enough,
> fall back to instance methods. (Or provide all of them, and let the users
> choose.)
> 

Till Py3K comes around, I'll choose one of these (haven't decided which
one).

>
> If the people you target can't handle Python, you shouldn't let them write
> Python -- write your own little language instead ;)
> 

I think I've amply demonstrated I'm not enough of a programmer to choose
_that_ solution ;)

Cheers,

Roeland



More information about the Python-list mailing list