Postfix/Prefix Operators (++,--)

Zath zathras_DESP at M_thwackey.com
Sat Jun 7 08:37:00 EDT 2003


Paraphrasing hostmaster:
> Why can't I do this in python ?
>    i,j=1,1
>    a=i++
>    b=j--

Suppose we *could*. What would this mean? Well, first off, lets
change the example slightly so that it _looks_ implementable.
   i,j=1,1
   a=i.pp()
   b=j.mm()

Where we expect x.pp() to act like x++, and x.mm() to act like x--.

What would these functions need to do? In order to keep the i++
semantics happy, the pp() function would need to look something
like this:

   def pp(self): # Version 1
      return self
      self=self+1 # This also needs executing...

But *that won't work* - you're changing what self is bound to - the
self+1 expression creates a new value for self to bind to, it
doesn't update the thing that self is bound to. (Let alone
continuing doing things after returning!)

So lets think - how _could_ we do this if we had C like variables?
If we make self a pointer at the memory location containing the
value then we could have something like this:
   def pp(*self): # Version 2
      return *self
      *self = *self +1 # We still need to get here.

In that situation (if you could implement this - you can't) we
would have your desired semantics. However this can't be done with
Python because a) ints are immutable - you can't update them
_in place_ which is what this requires b) You can't do things
in functions in python after returning the values. (In exactly the same
way as in C you can't implement postfix type functions...)

You can emulate however the following behaviour:
   i,j=1,1
   a=++i
   b=++j

Since you update the value before returning it, but it does require
you to create mutable integers, and your user code could look like
this:
   i,j=mInt(1),mInt(1)
   a=i.pp()
   b=j.mm()

Your mutable Int class would inherit from int, and implement the
same interface, and could partially look like this:
class mInt(int):
   def __init__(self,*args):
       super(mInt, self).__init__(self,*args)
       self._value = args[0]
   def __repr__(self):
       return str(self._value)
   def pp(self):
      self._value+=1
      return self
   def __add__(self,x):
      return mInt(self._value+x)
   def mm(self):
      self._value-=1
      return self
   def __add__(self,x):
      return mInt(self._value+x)
   def __sub__(self,x):
      return mInt(self._value-x)

The key difference though is that with this example, you've
changed ints from being immutable to mutable objects. Also you'd
have to allow postfix operations - operations that continue
doing things after returning - without explicit callback.

Also your new syntax could be confusing for C users:

   x.pp() equivalent to ++x
   x.mm() equivalent to --x

Given there's few situations where:
   a=c++

Is truly clearer than:
   a  = c
   c += 1

I'm personally glad that somethings that can be considered
immutable stay that way!


Michael





More information about the Python-list mailing list