in-place exponentiation incongruities

Giacomo Alzetta giacomo.alzetta at gmail.com
Sun Aug 12 07:55:19 EDT 2012


Il giorno domenica 12 agosto 2012 13:03:08 UTC+2, Steven D'Aprano ha scritto:
> On Sun, 12 Aug 2012 00:14:27 -0700, Giacomo Alzetta wrote:
> 
> 
> 
> > From The Number Protocol(http://docs.python.org/c-api/number.html). The
> 
> > full text is:
> 
> > 
> 
> > PyObject* PyNumber_InPlacePower(PyObject *o1, PyObject *o2, PyObject
> 
> > *o3)
> 
> >     Return value: New reference.
> 
> > 
> 
> >     **See the built-in function pow().** Returns NULL on failure. The
> 
> >     operation is done in-place when o1 supports it. This is the
> 
> >     equivalent of the Python statement o1 **= o2 when o3 is Py_None, or
> 
> >     an in-place variant of pow(o1, o2, o3) otherwise. If o3 is to be
> 
> >     ignored, pass Py_None in its place (passing NULL for o3 would cause
> 
> >     an illegal memory access).
> 
> > 
> 
> > The first thing that this text does is referring to the **function**
> 
> > pow, which takes three arguments. And since the documentation of the
> 
> > operator module states that "The operator module exports a set of
> 
> > efficient functions corresponding to the intrinsic operators of
> 
> > Python.", I'd expect the ipow to have three arguments, the third being
> 
> > optional.
> 
> 
> 
> Why? There is no three-argument operator. There is a three-argument 
> 
> function, pow, but you don't need the operator module for that, it is 
> 
> built-in. There is no in-place three-argument operator, and no in-place 
> 
> three-argument function in the operator module.
> 
> 
> 
> Arguing from "consistency" is not going to get you very far, since it is 
> 
> already consistent:
> 
> 
> 
> In-place binary operator: **=
> 
> In-place binary function: operator.ipow
> 
> 
> 
> In-place three-argument operator: none
> 
> In-place three-argument function: none
> 
> 
> 
> If you decide to make a feature-request, you need to argue from 
> 
> usefulness, not consistency.
> 
> 
> 
> http://bugs.python.org
> 
> 
> 
> Remember that the Python 2.x branch is now in feature-freeze, so new 
> 
> features only apply to Python 3.x.
> 
> 
> 
> 
> 
> > With normal exponentiation you have ** referring to the 2-argument
> 
> > variant, and "pow" providing the ability to use the third argument. 
> 
> 
> 
> Correct.
> 
> 
> 
> 
> 
> > At the moment in-place exponentiation you have "**=" referring to the
> 
> > 2-argument variant(and this is consistent), while operator.ipow also
> 
> > referring to it. 
> 
> 
> 
> Correct. Both **= and ipow match the ** operator, which only takes two 
> 
> arguments.
> 
> 
> 
> 
> 
> > So providing an ipow with the third argument would just
> 
> > increase consistency in the language, 
> 
> 
> 
> Consistency with something other than **=  would be inconsistency.
> 
> 
> 
> 
> 
> 
> 
> > and provide a feature that at the
> 
> > moment is not present. (well if the designers of python care really much
> 
> > about consistency they'd probably add an "ipow" built-in function, so
> 
> > that you don't have to import it from "operator").
> 
> 
> 
> Not everything needs to be a built-in function.
> 
> 
> 
> 
> 
> 
> 
> -- 
> 
> Steven

Probably I've mixed things up.

What I mean is: when you implement a new type as a C extension you have to provide special methods through the NumberMethods struct. In this struct both the power and in-place power operations have three arguments.
Now, suppose I implement the three argument variant of the in-place power in a class. No user would be able to call my C function with a non-None third argument, while he would be able to call the normal version with the third argument.

This is what I find inconsistent. either provide a way to call also the in-place exponentiation with three arguments, or define it as a binary function.
Having it as a ternary function, but only from the C-side is quite strange.




More information about the Python-list mailing list