On Sat, Dec 4, 2021 at 3:47 AM Andrew Jaffe <a.h.jaffe@gmail.com> wrote:
b) I think another motivation that hasn't been highlighted is teaching -- perhaps surprisingly, I think adding this will make some aspects of teaching *easier*. Mutable defaults are known to be confusing to Python neophytes; I have certainly found this when I have both explictly taught or just had to explain some aspect of python.
Yes, definitely, that is a huge advantage IMO.
c) I would probably use this, but can we confirm something that isn't explicit in the pep:
Does this
def fn(word, num=>len(word)):...
mean the same as this? (except for the default for word):
def fn(word="foo", num=>len(word):...
I can't think of any argument they shouldn't but in fact the former reads funny to me.
Not sure what you mean by "mean the same", but the rule is simple: the expression is allowed to refer to anything in its current context. That includes other parameters. If 'word' has no default, then you cannot call the function without providing a word. Defaults are irrelevant if you get TypeError prior to that point. If you pass a value for "word", then the two will behave identically. Either you pass a value for num and it uses that, or you don't pass a value and it uses the length of word as the default. Things are a little more messy if you refer to parameters to the right of them. In my current reference implementation, this is valid, but will raise UnboundLocalError if those parameters also have late-bound defaults and were not given values. But don't depend on that, and it may become more strictly invalid.
Also, relatedly, I assume that late-bound arguments can refer to names that only exist in the caller's environment, but haven't even been bound at definition time? And that if they are not bound at call time, there is a syntax error?
Not a syntax error. It's like any other name reference; if you refer to something that doesn't exist, you'll get a NameError. You're absolutely welcome - and encouraged - to refer to nonlocal (global or closure) names from your environment. Incidentally, I don't yet have any good examples to back this up, but this sort of thing would be completely valid: class X: def method(self, size=>self.n): ... Technically it's the same thing as "a, size=>len(a)" in that it's referring to an earlier parameter, but to a human, this might be seen as a different and also valid use-case. ChrisA