
On Tue, Oct 26, 2021 at 10:20 AM Kyle Lahnakoski <kyle@lahnakoski.com> wrote:
I was concerned with this proposal at first because an inner function definition may be ambiguous:
def do_work(): a = ['this', 'is', 'a', 'list'] def range(a, min=0, max = defer len(a)): return a[min:max]
which `a` does `len(a)` refer to?
In this case, there's absolutely no ambiguity; it will refer to the parameter a. There are other situations that are less clear, but for the most part, assume that a late-bound default is evaluated in the context of the function body.
Can deferred defaults refer to variables in scope? Can I use this to evaluate arguments lazily?
def coalesce(a, b): def _coalesce(x = defer a(), y = defer b()): if x is None: return x return y _coalesce()
def expensive_method(): return 84
print(coalesce(lambda: 42, expensive_method))
They can refer to variables in scope, but all argument defaults are evaluated before the body of the function begins. This is one reason NOT to call this "defer", since this isn't a generic tool for late-evaluated thunks; it is broadly equivalent to "if y is not set: y = b()" at the start of the function. ChrisA