
On Tue, 26 Oct 2021, Ricky Teachey wrote:
At bottom I guess I'd describe the problem this way: with most APIs, there is a way to PASS SOMETHING that says "give me the default". With this proposed API, we don't have that; the only want to say "give me the default" is to NOT pass something.
I don't KNOW if that's a problem, it just feels like one.
I agree that it's annoying, but it's actually an existing problem with early-bound defaults too. Consider: ``` def f(eggs = [], spam = {}): ... ``` There isn't an easy way to get the defaults for the arguments, because they're not just *any* `[]` or `{}`, they're a specific list and dict. So if you want to specify a value for the second argument but not the first, you'd need to do one of the following: ``` f(spam = {'more'}) f(f.__defaults__[0], {'more'}) ``` The former would work just as well with PEP 671. The latter depends on introspection, which we're still working out. Unfortunately, even if we can get access to the code that produces the default, we won't be able to actually call it, because it needs to be called from the function's scope. For example, consider: ``` def g(eggs := [], spam := {}): ... ``` In this simple case, there are no dependencies, so we could do something like this: ``` g(g.__defaults__[0](), {'more'}) ``` But in general we won't be able to make this call, because we don't have the scope until `g` gets called and its scope created... So there is a bit of functionality loss with PEP 671, though I'm not sure it's that big a deal. I wonder if it would make sense to offer a "missing argument" object (builtin? attribute of inspect.Parameter? attribute of types.FunctionType?) that actually simulates the behavior of that argument not being passed. Let me call it `_missing` for now. This would actually make it far easier to accomplish "pass in the second argument but not the first", both with early- and late-binding defaults: ``` f(_missing, {'more'}) g(_missing, {'more'}) ``` I started thinking about `_missing` when thinking about how to implement late-binding defaults. It's at least one way to do it (then the function itself could even do the argument checks), though perhaps there are simpler ways that avoid the ref count increments. Erik -- Erik Demaine | edemaine@mit.edu | http://erikdemaine.org/