(original) (raw)


A very quick reply, more tomorrow.

On 10/09/2013 02:15 AM, Steven D'Aprano wrote:
I note that in your example above, you put the comma outside the square   
bracket:

def addch([y, x,] ch, [attr], /):

which seems perfectly readable to me.





It becomes less readable / more tiresome with nested groups. Which
square bracket should the comma come after? Anyway, it seems like
you agree with the syntactic requirement for other reasons.



(And, I already fixed the two places in the PEP where I had the
comma outside the square brackets, thanks for pointing it out.)




I would much prefer Undefined and UndefinedType. That matches other
singletons like None, NotImplemented, Ellipsis, even True and False.




You're probably right.






[Bikeshed: perhaps Missing is more appropriate than Undefined? After
all, the parameter is defined, only the value is missing.]




Let the bikeshedding begin!






[Argument for allowing explicitly passing "undefined":
this lets the iterable in foo(*iterable) yield "undefined",
which could be convenient]




That's a good thought. But I'd be interested in more debate on the
subject to see if people have other good reasons for/against
encouraging explicitly using "undefined".






Because I think this is important, I'm going to raise it again: I think
it is important for the PEP to justify why user functions cannot specify
arbitrary values as defaults, not just Undefined.




Primarily because this codifies existing practice. C bulitins with
positional-only decide how to assign their arguments based on how
many there are, and when a parameter doesn't receive an argument it
almost never gets a default value. I was trying to preserve these
exact semantics, which is where the optional groups came from. And
since I already had optional groups and "undefined", that seemed
sufficient.



I'll also admit, I mainly ruled it out back before the prefer-left
disambiguation rule, and allowing default values for positional-only
led to loads of ambiguity. I hadn't reconsidered the restriction in
light of the new rule.



But I still think the semantics get weird quickly. Consider:

def bar([a=7, b,] c, [d,] /):

Default values would have to grow from the outside in, staying away
from the required positional-only parameter group. So on the left
side they'd be backwards.



And if you call bar() with two arguments, you'd get (a b c), not (c
d). In fact there'd be no way of specifying

d without providing four arguments. By that token there'd be no way
of calling bar() and specifying d without stomping on the default
value for a.



I agree I should do a better job of justifying the design in a
future revision. I'd have to think long and hard before allowing
default values for positional-only arguments... and that's a
restriction I wouldn't relax for Argument Clinic.



Anyway it's late, more tomorrow.





/arry