On Sun, Oct 24, 2021 at 7:58 AM Bruce Leban
On Sat, Oct 23, 2021 at 12:56 PM Guido van Rossum
wrote: I like that you're trying to fix this wart! I think that using a different syntax may be the only way out. My own bikeshed color to try would be `=>`, assuming we'll introduce `(x) => x+1` as the new lambda syntax, but I can see problems with both as well :-).
+1 to this spelling. I started writing a message arguing that this should be spelled with lambda because the fact that you're (effectively) writing a function should be explicit (see below). But the syntax is ugly needing both a lambda and a variant = operator. This solves that elegantly.
Agreed; if it needs to remain self-contained, then yes, it would have to be a function, and there'd be good reason for making it look like one. As it is, it's more just "code that happens at the start of the function", but I think there's still value in using a syntax that people understand as a late binding system (as lambda functions will be).
On Sat, Oct 23, 2021 at 9:10 AM Chris Angelico
wrote: Proposal: Proper syntax and support for late-bound argument defaults.
def bisect(a, x, lo=0, hi=:len(a)): if lo < 0: raise ValueError('lo must be non-negative')
The syntax I've chosen is deliberately subtle, since - in many many cases - it won't make any difference whether the argument is early or late bound, so they should look similar.
I think a subtle difference in syntax is a bad idea since this is not a subtle difference in behavior. If it makes no difference whether the argument is early or late bound then you wouldn't be using it.
There IS a difference, but the difference should be subtle. Consider: x = 5 x = 5. These are deliberately similar, but they are quite definitely different, and they behave differently. (You can't use the second one to index a list, for instance.) Does the difference matter? Absolutely. Does the similarity matter? Yep. Similar things should look similar. The current front-runner syntax is: def bisect(a, x, lo=0, hi=>len(a)): This is only slightly less subtle. It's still a one-character difference which means that instead of being evaluated at definition time, it's evaluated at call time. This is deliberate; it should still look like (a) a parameter named "hi", (b) which is optional, and (c) which will default to the result of evaluating "len(a)". That's a good thing.
Here's one way you could imagine writing this today:
def bisect(a, x, lo=0, hi=lambda: len(a)): hi = hi() if callable(hi) else hi ...
which is clumsy and more importantly doesn't work because the binding of the lambda occurs in the function definition context which doesn't have access to the other parameters.
Right. It also doesn't solve the help() problem, since it's just going to show the (not-very-helpful) repr of a lambda function. It's not really much better than using object() as a sentinel, although it does at least avoid the global-pollution problem. It seems like there's broad interest in this, but a lot of details to nut out. I think it may be time for me to write up a full PEP. Guido, if I'm understanding recent SC decisions correctly, a PEP editor can self-sponsor, correct? ChrisA