On Thu, Dec 9, 2021 at 3:16 PM Rob Cliffe via Python-ideas
<python-ideas@python.org> wrote:
>
> Objections to PEP 671 - Summary
> There seems to be a problem understanding what the objections to PEP 671 are. 
>  Chris A wrote:
> "Part of the problem is that it is really REALLY hard to figure out what the 
> actual objections are. I asked, and the one clear answer I got was one 
> subjective opinion that the cognitive load exceeded the benefit. Great! 
> That's one person's concern. I've responded to that by clarifying parts of 
> the cognitive load problem, and that's about as far as that can go. But if 
> there's nothing more specific than that, what do you want me to respond to? 
> How can I address the objections if the objections are as vague as you're 
> describing?"
>
> Well, I have AFAIK re-read every post in the threads and am attempting to 
> summarise the objections to PEP 671 that I have found.
>

Thank you. Much appreciated.

> Disclaimer: I do NOT claim this is a completely objective survey.  I think by 
> now everyone knows on which side of the fence I sit.  In some places I have 
> added my own (biased) comments.  Nonetheless I have honestly tried to make a 
> fair selection from all the relevant, reasonably important posts.  And if 
> anyone thinks that their, or anyone else's objection(s) have been 
> omitted/understated/misrepresented, they are welcome to edit this post and 
> put the result in a new one.
> Disclaimer: I have not referred to Steven d'Aprano's posts, because I lack 
> the time (ability?) to understand them all.  AFAICT he is in favour of 
> something like this PEP, but a bit different.
>

Unfortunately, neither do I fully understand them, so we're going to
have to wait for his clarifications. Or, better, a reference
implementation. Until then, let's leave that all aside.

> AFAIK these were all the objections that were raised.  There may be some 
> overlap or some sub-cases but this is how I've classified them:
>     (A) Don't like the proposed `=>` syntax.
>     (B) Too few use cases to bother making a change to the language.  Status 
> quo wins.
>     (C) Some form of "deferred evaluation object" would do everything this 
> PEP does and more, and might be incompatible with it.
>     (D) The (late-binding) default value should be a first-class object that 
> can be accessed and manipulated.
>     (E) Calculation of a "default value" should be done in the function body, 
> not the function header.
>     (F) Concerns that functions using late-bound defaults were harder to wrap.
>     (G) Backward compatibility.
>     (H) No other language supports both early- and late-binding.
>

(A) I have a few other syntaxes in the PEP, but if syntax is the only
issue and I haven't listed someone's preferred syntax, I would be
happy to consider others.

(B) I've shown some use cases. If you think these aren't of value, no
problem, but there's nothing to answer here.

(C) This has been asserted without evidence repeatedly. So far, I have
yet to see an example of how a deferred-evaluation object could
replace default argument handling; the examples have all been massive
overkill eg  options for parallelism, and entail lots of extra syntax.
I'm also not convinced that they'd make late-bound defaults useless,
and that hasn't really been explained either.

(D) Understood. My response is two-fold: firstly, no other expression
in Python is a first-class object, and secondly, the manipulations
possible wouldn't be sufficiently general to cover all use-cases. I do
provide a textual representation of the default, which in simple
situations could be eval'd; in complex situations, nothing external
would work anyway.

(E) That's purely a matter of opinion, but if that's the case, why
aren't *all* defaults done in the body? Why do we have argument
defaults in the function header at all? Surely that's of value. It
certainly has been to me.

(F) Also a matter of opinion, given that *a,**kw is the most common
wrapping technique used, and will work reliably. Function signature
algebra is a much larger challenge than this.

(G) I'm not breaking compatibility in any way.

(H) This is true. But if the two syntaxes can be sufficiently similar,
the cost should be low, and the feature benefit would be high. Early
binding lets you "def f(x=x):" in a loop and capture each x as it goes
by. Late binding lets you "def f(x=>[]):" and get a new list every
time. Both have their places.

If Python had had late binding from the start, and no early binding,
we would have developed idioms for early binding (most likely a
decorator that captures values or something like that). Both
behaviours are sufficiently useful that programmers WILL implement
them, language support or not.

> I quote from one of Chris A's replies re a `defer` keyword:
> 'The trouble is that this actually would be incompatible. If you can defer an 
> expensive calculation and have some "placeholder" value in the variable 
> 'result', then logically, you should be able to have that placeholder as a 
> function default argument, which would be an early-bound default of the 
> placeholder.  That is quite different in behaviour from a late-bound default, 
> so if I were to use the word "defer" for late-bound defaults, it would 
> actually prevent the more general proposal.'
>

The incompatibility here, btw, would be using a "defer" keyword to
mean late-binding, which isn't the same thing as a "defer expr"
keyword that creates a deferred expression. PEP 671 would not be
incompatible with a generic deferred-expression concept, as long as
they don't use the same word.

> (D) The (late-binding) default value should be a first-class object that can 
> be accessed and manipulated.
>
>     Eric V.Smith: [AFAIU, paraphrased] I want the default value to be an 
> object that I can inspect and change.
>     David Mertz: "For the reasons Eric Smith and others have pointed out, I 
> really WANT to keep inspectability of function signatures."
>     Stephen J. Turnbull: "More than any of these issues, the lack of a 
> well-defined, properly introspectable object bothers me."
>
> Chris A gave a reply including 'If you consider the equivalent to be a line 
> of code in the function body, then the signature has become MASSIVELY more 
> useful.  Instead of simply seeing "x=<object object at 0x7fba1b318690>", you 
> can see "x=>[]" and be able to see what the value would be.'
>

Correct. In general, expressions are not first-class objects in
Python; they only become them when turned into functions or classes
(including the special functions used by genexps/comps). We do not
have an introspectable, externally-testable, first-class object to
represent any other expression:

x = 1/y if y else "invalid"

There's no object for "1/y". Trying to create one would be a nightmare
of subtleties, where assignment expressions would break things,
nonlocal variable references would become tricky, etc, etc. Similarly:

def f(y):
    def g(x=1/y):
        ...
    return g

There's no object for "1/y" here either. As an early-bound default,
the expression is simply inlined into the body of f, as part of the
construction of the function. Now with late-bound defaults:

>>> def f(y):
...     def g(x=>1/y): ...
...     return g
...
>>> f(4).__defaults_extra__
('1 / y',)

... you still don't get a first-class object for the expression, but
you DO get a string constant that describes it. What is it about this
third example that makes the bar so much higher than for the other
two?



Thank you for this summary. Are there any objections still unanswered?

Which of these parts is important enough to add to the PEP? I think
I'll be adding a section on introspectability, since it seems to be a
hot topic, but I'm not sure about the others.

ChrisA
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/2QPKHWMQ4QOHFN65XBVXDF6E4HY4ARYA/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to