
Rob Cliffe via Python-ideas writes:
So PEP 671 merely attempts to restore functionality that was (regrettably IMO) left out as a result of that early decision.
This is a *new* feature, which adds syntax. A lot of contributors to this thread think it's useful enough to overcome the normal Pythonic reluctance to add (1) new features that are syntactic sugar for one-line statements, and (2) new syntax. Others disagree. This utility is either going to be enough to convince the SC, or it's not. It's clear that the battle lines are being drawn.[1] So let's stop trying to convince each other of whether this is a good proposal or not, and turn to making it the best proposal possible so as to give proponents the best chance of getting it in, and to give opponents the least unpalatable misfeature ;-) if it does get in. Still on the agenda as far as I can see: 1. Syntax. The proposals I can recall are a. x=>default b. *x=default c. x=@default d. maybe putting * or @ on the opposite component in b and c? e. a keyword before default such as "late" or "defer". Others? I believe Chris currently favors a. 2. The implementation. a. Keep an abstract representation of the default expression as a string in a dunder, and prefix the compiled body with code to evaluate it in the appropriate namespace. b. As in a, but the abstract representation is an AST or similar. c. Wrap the evaluation in a function (or function-like object) and invoke it before the compiled body (this was suggested by Steven d'Aprano as a compromise, I believe). d. Wrap the evalution in a general-purpose deferred object (this is not in the scope of PEP 671, discussion below). I believe Chris's current reference implementation is a (or if I got that wrong, closer to a than any of the others). It would be helpful to the discussion if Chris starts by striking any of the above that he's unwilling to implement. A question for Chris: In your proposal, as I understand it, an expensive default expression would always be evaluated, even if it's not always needed. Eg, in this toy example: def foo(x:int=>expensive()): if delphic_oracle(): return x else: return 0 expensive() is always evaluated. In that (presumably quite rare) case, we'd just use a sentinel instead, of course. I have further two comments, which are mostly addressed to Steve, I guess. First, I don't really understand Steve's intended difference between 2c and 2d. Second, as I understand them, both 2c and 2d encapsulate the expression in bytecode, so the nice property of introspectability of the expression is lost. I guess you can decompile it more easily than if it's just interpolated into the function body, but if it's implemented as a closure, don't we lose the identity of the identifiers in the expression? And if it's not (eg, the function-like thing encapsulates an abstract representation of the expression rather than bytecode that computes it), what's the point of 2c? I don't see how it has any advantage over 2a or 2b. Footnotes: [1] Nobody's right, if everybody's wrong. -- Stephen Stills You can never have too many Steves in a discussion!