On Sun, Sep 27, 2020 at 5:58 PM Brett Cannon <br...@python.org> wrote:

>
>
> On Sun, Sep 27, 2020 at 2:58 PM Guido van Rossum <gu...@python.org> wrote:
>
>> Hm... IIRC the reason why we did this for `__r*__` is because the more
>> derived class might want to return an instance of that class, and we can't
>> assume that the less derived class knows how to create an instance of the
>> more derived class (the `__init__` signatures might differ).
>>
>
> Yep, that's what the data model docs suggest (see the note at
> https://docs.python.org/3/reference/datamodel.html#object.__ror__).
>
> But the interesting bit is skipping the call of __r*__ when `lhs.__r*__ ==
> rhs.__r*__` (as long as the derived class requirements are met). That's the
> difference that I'm really curious about compared to rich comparisons and
> their inverse which don't have this call avoidance.
>
> To help visualize all of this, you can see
> https://github.com/brettcannon/desugar/blob/066f16c00a2c78784bfb18eec31476df045cefe5/desugar/operator.py#L93-L103
> for binary arithmetic operators compared to
> https://github.com/brettcannon/desugar/blob/066f16c00a2c78784bfb18eec31476df045cefe5/desugar/operator.py#L273-L280
> for rich comparisons.
>

Ooh, interesting. (Aren't you missing a few checks for MISSING in the elif
or else branches?)

Let me guess some more (I'm on a rare caffeine high since 9am so we'll see
how this goes :-).

The idea is clearly that if lhs and rhs are the same class we don't bother
calling `__r*__` (because if `__*__` didn't do it there's no reason that
`__r*__` would be any different).

Are you sure you read things right, and `__r*__` is skipped when the
`__r*__` methods are the same, and not only when the lhs and rhs classes
are the same?

It does seem kind of a pointless optimization, since if the first call is
successful we'll skip the second call anyway, and if it returns
NotImplemented, well, if our assumption that `__r*__` is going to do the
same, it's going to be an error anyway. I wonder if this was always there?
Maybe we should study the git blame some more.

And why don't we do this for rich comparisons? Probably because the logic
is completely separate. :-( And maybe when we did rich comparisons (nearly
a decade after the original binary operator overloading IIRC) the
optimization idea didn't occur to us, or maybe we realized that we'd be
optimizing an error case. Or maybe because rich comparisons were trying to
somehow model the earlier `__cmp__`?


> [SNIP]
>> I think we could try to change it but it would require a very careful
>> risk analysis.
>>
>
> I'm not sure how critical it is to change. I'm sure there's some potential
> perf gain by avoiding the (potentially) unnecessary call, but I also don't
> know if people have implemented these functions in such a way that skipping
> the inverse operation on the right-hand side object would break something.
> Would abuse of the syntax make a difference (e.g. making `>` do something
> magical)?
>

I don't know, PEP 207 explicitly says the reflexivity assumptions are
assumed. I guess I misunderstood your question for clarification as a
suggestion to change.

I feel this requires more careful thought than I can muster tonight.


> -Brett
>
>
>>
>> On Sun, Sep 27, 2020 at 1:41 PM Brett Cannon <br...@python.org> wrote:
>>
>>> When you do a binary arithmetic operation, one of the things that
>>> dictates whether the left-hand side's __*__ method is called before the
>>> right-hand side's __r*__ method is if the left-hand side's __r*__ differs
>>> (there's also the fact __r*__ methods are not called if. the types are the
>>> same). Presumably this is because you only care about giving precedence to
>>> the right-hand side when it would actually matter due to a difference in
>>> implementation (with the assumption that there isn't a specific need to get
>>> the right-hand side special dispensation to participate in the operation).
>>>
>>> But with rich comparisons there doesn't seem to be an equivalent check
>>> for a difference in method implementation. Why is that? Is it because we
>>> don't want to assume that if someone bothered to implement both __gt__ and
>>> __lt__ that they would not necessarily be the inverse of each other like
>>> __add__ and __radd__?
>>> _______________________________________________
>>> Python-Dev mailing list -- python-dev@python.org
>>> To unsubscribe send an email to python-dev-le...@python.org
>>> https://mail.python.org/mailman3/lists/python-dev.python.org/
>>> Message archived at
>>> https://mail.python.org/archives/list/python-dev@python.org/message/7NZUCODEAPQFMRFXYRMGJXDSIS3WJYIV/
>>> Code of Conduct: http://python.org/psf/codeofconduct/
>>>
>>
>>
>> --
>> --Guido van Rossum (python.org/~guido)
>> *Pronouns: he/him **(why is my pronoun here?)*
>> <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
>>
>

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*
<http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/JIAC23EBW6IHGDYQFTHS44YJRROVO226/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to