
On Mon, Dec 6, 2021 at 10:04 PM Paul Moore <p.f.moore@gmail.com> wrote:
Here's a prototype implementation, and a demonstration of how it would be used to implement late bound arguments. Please note, I understand that the syntax here is horrible. That's exactly the point, this needs language support to be non-horrible. That's what a "deferred expression" proposal would provide.
# Explicitly creating Deferred objects is horrible, this is the bit that *really* needs language support class Deferred: def __init__(self, callable): self.callable = callable
# This could easily be a builtin function (or an operator if people prefer syntax) once we have deferred objects. def undefer(expr): if isinstance(expr, Deferred): return expr.callable() return expr
x = 12 # def f(a=defer x): def f(a=Deferred(lambda: x)): a = undefer(a) return a
assert f(9) == 9 assert f() == 12 x = 8 assert f() == 8 assert f(9) == 9
If anyone wants to take this and make a *proper* deferred object proposal out of it, then please do so. If not, then at a minimum I think this offers something vaguely concrete to discuss regarding the "why deferred objects are a more general solution to the late bound argument" question.
The reason I consider this to be an independent proposal, and NOT a mechanism for late-bound defaults, is this problem: def f(lst, n=>len(lst)): lst.append(1) print(n) f([10, 20, 30]) A late-bound default should print 3. A deferred expression should print 4. They're not a more general solution to the same question; they're a solution to a different question that has some overlap in what it can achieve. A None-coalescing operator would also have some overlap with each of the above, but it is, again, not the same thing. ChrisA