[Python-Dev] PEP 203 Augmented Assignment

Thomas Wouters thomas@xs4all.net
Tue, 25 Jul 2000 23:03:23 +0200


No, this isn't the first full draft of the PEP :P While writing up the
proposed VM changes, I came to the conclusion my patch was all wrong, and I
would like some input in case I forgot something.

The current patch introduces the following bytecodes:

GETSET_SUBSCR
GETSET_SLICE
GETSET_SLICE+1
GETSET_SLICE+2
GETSET_SLICE+3
GETSET_ATTR
GETSET_NAME
GETSET_FAST
GETSET_GLOBAL

Each bytecode does the loading of the object, the actual operation it is
supposed to perform, and the storing in the original place. All opcodes get
an argument to specify which operation should be performed, which is also
where the need for 2-argument opcodes comes from: the NAME/FAST/GLOBAL
opcodes need both a name-index and an opcode argument.

My excuse for this design is similar to Guido's excuse for the current
Python parser: I was young, I was foolish, and I didn't know how to reuse
things, only how to *add* things ;) I was also intimidated by the whole idea
of a stack, having never really programmed in a low-level programming
language before.

I now realize only 11 new opcodes are necessary, and it can even be reduced
to 1, by splitting the operation into seperate LOAD, <operation>, and STORE
instructions, with a few ROT_TWO and ROT_THREE's mixed in. <operation> could
be a new bytecode for each operation (11 in total) or a single 'AUGOP'
bytecode with an argument to specify the operation.

I think it's less elegant from the bytecode point of view, but it does
require a lot less changes in ceval/compile. There is only one significant
difference between the current version and this, and that's behaviour in the
face of threads.

I had originally seen augmented assignment as a way to increment a counter
'thread-safe': the load and store operation are done in one bytecode, and
can thus not be interrupted by a thread switch. But after thinking about it,
it doesn't make that much sense. It only works for builtin types, not for
classes defining a __op_ab__, and possibly not for extention types. In fact,
there might be some possibility for a thread switch even in builtin types,
though I have never looked at that.

Opinions ? Is the semi-reliability in the face of threads a good idea ? Did
I miss anything important about the current implementation ? Should I forget
about this idea and keep the patch as it is (and go back to my PEP) or
should I rewrite the patch and then rewrite the PEP ?

This alternate implementation would eradicate my next-to-last objection to
including the patch, I think, but we'll discuss the last one, the naming of
the __hooks__, after I finish the bloody PEP ;-)

-- 
Thomas Wouters <thomas@xs4all.net>

Hi! I'm a .signature virus! copy me into your .signature file to help me spread!