On Tue, 26 Oct 2021, Steven D'Aprano wrote:
def func(x=x, y=>x) # or func(x=x, @y=x)
This makes me think of a "real" use-case for assigning all early-bound
defaults before late-bound defaults: consider using closure hacks (my main use
of early-bound defaults) together with late-bound defaults, as in
```
for i in range(n):
def func(arg := expensive(i), i = i):
...
```
I think it's pretty common to put closure hacks at the end, so they don't get
in the way of the caller. (The intent is that the caller never specifies
those arguments.) But then it'd be nice to be able to use those variables in
the late-bound defaults.
I can't say this is beautiful code, but it is an application and would
probably be convenient.
On Tue, 26 Oct 2021, Eric V. Smith wrote:
Among my objections to this proposal is introspection: how would that work?
The PEP mentions that the text of the expression would be available for
introspection, but that doesn't seem very useful.
I think what would make sense is for code objects to be visible, in the same
way as `func.__code__`. But it's definitely worth fleshing out whether:
1. Late-bound defaults are in `func.__defaults__` and `func.__kwdefaults__` --
where code objects are treated as special kind of default values. This seems
problematic because we can't distinguish between a late-bound default and an
early-bound default that is a code object.
or
2. There are new defaults like `func.__late_defaults__` and
`func.__late_kwdefaults__`. The issue here is that it's not clear in what
order to mix `func.__defaults__` and `func.__late_defaults` (each a tuple).
Perhaps most natural is to add a new introspection object, say LateDefault,
that can take place as a default value (but can't be used as an early-bound
default?), and has a __code__ attribute.
---
By the way, another thing missing from the PEP: presumably lambda expressions
can also have late-bound defaults?
On Tue, 26 Oct 2021, Marc-Andre Lemburg wrote:
Now, it may not be obvious, but the key advantage of such
deferred objects is that you can pass them around, i.e. the
"defer os.listdir(DEFAULT_DIR)" could also be passed in via
another function.
Are deferred code pieces are dynamically scoped, i.e., they are evaluated in
whatever scope they end up getting evaluated? That would certainly
interesting, but also kind of dangerous (about as dangerous as eval), and I
imagine fairly prone to error if they get passed around a lot. If they're
*not* dynamically scoped, then I think they're equivalent to lambda, and then
they don't solve the default parameter problem, because they'll be evaluated
in the function's enclosing scope instead of the function's scope.
Erik
--
Erik Demaine | edema...@mit.edu | http://erikdemaine.org/
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/python-ideas@python.org/message/UPC3AX7ESRJ57IJS4DWEV4MS3N4SIISO/
Code of Conduct: http://python.org/psf/codeofconduct/