On Wed, Jan 13, 2021 at 6:11 PM Ethan Furman <et...@stoneleaf.us> wrote:
>
> On 1/12/21 10:37 PM, Chris Angelico wrote:
> > On Wed, Jan 13, 2021 at 5:05 PM Steven D'Aprano wrote:
> >>
> >> On Wed, Jan 13, 2021 at 04:47:06AM +1100, Chris Angelico wrote:
> >>
> >>> That'd leave open
> >>> the option for "foo() if x else foo()" to be optimized down to just
> >>> "foo()", although I don't think that particular one is needed.
> >>
> >> That would be an unsafe optimization. Not all objets are representable
> >> as truthy/falsey values
>
> >> Not even all builtin values. This is in Python 3.9:
> >>
> >>      >>> bool(NotImplemented)
> >>      <stdin>:1: DeprecationWarning: NotImplemented should not be used in
> >>      a boolean context
> >>      True
> >>
> >> I believe that 3.10 makes it an error. If not 3.10, then it will surely
> >> happen soon. But even without the change to NotImplemented, it has never
> >> been the case that *every* object is guaranteed to be either truthy or
> >> falsey. At least not since the Python 1.x `__nonzero__` dunder was put
> >> into the language.
> >
> > But this is exactly where we started: with a boolification that fails,
> > in a context where the result wouldn't actually change anything.
> > Actually calling bool() on something will continue to have the
> > behaviour you're describing, but if the truthiness or falsiness would
> > make no difference, is the interpreter required to find out?
>
> Yes.
>
> Optimizations are an implementation detail, and implementation details should 
> not change the language.
>

The language can also be defined in an optimization-friendly way,
though. Consider how we got positional-only arguments in Python: first
they existed in C-implemented functions in CPython, even though they
couldn't exist in pure Python code, and then the functionality got
added to the language definition, thus permitting the optimization.

Or consider dictionary lookup. Most people treat it as "find a key
which is equal to the one you're looking for", but the actual
definition is "find a key which is identical to, or equal to, the one
you're looking for". That's partly to ensure that weird cases like NaN
don't break too badly, but also it means that x.__eq__(x) doesn't have
to be called all the time.

The topic under discussion is a language definition. Choosing to
permit the optimization doesn't mean that the implementation detail
changes the language. Choosing to deny it means there won't be an
optimization.

I personally don't see any reason to force Python to calculate
something unnecessarily, given that this is *already* happening in
other situations (see the "if a and b:" optimization, which doesn't
boolify twice).

ChrisA
_______________________________________________
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/SAUNDT7XTTFWREABUXPE2OKWI6KBQECO/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to