On Sat, Dec 11, 2021 at 5:35 PM Stephen J. Turnbull <stephenjturnbull@gmail.com> wrote:
Eric V. Smith writes:
That's why I think we should have a larger concept that just late-bound parameters: I think there's a general concept here that can be extended beyond parameters.
One advantage of Chris's preferred syntax is that as a default in a function's parameter list it could do whatever it needs to do there, while in an executable context, it could return the object, as := does. That's a bit inconsistent and quite ugly, I guess, and it might lead to code like
def foo(x=>[]): a = bar() return x
foo(x=>[a])
which I think would be rather confusing. Whether it would be acceptable is a question of how often it would be used as an assignment expression rather than as an assignment statement.
I'm not sure what that last line would mean. My proposal doesn't change the call site in any way, so I'm trying to figure out what you mean by that call. Are you saying that x=>[a] would be an assignment statement that sets x to an unevaluated expression? If so, that's independent of the default argument. If it's a special way to pass keyword arguments to a function, which passes unevaluated expressions that are collapsed into values upon usage, then this would be extremely interesting, but highly bizarre behaviour. It would also require significant changes to the way that nonlocal names are looked up (or would be restricted in what nonlocals it can refer to, possibly none at all).
later, we'd have two ways to specify late-bound parameters [0].
We might want that anyway. One of the aspects of Chris's proposal is that late-bound parameters get resolved to objects in a well-specified (if complicated) order at call time, before entering the function body. In
foo(x=othermodule.bar())
the compiler cannot know that x's value is a "deferred object" (aside: how about "autoevaluated expression object", presumably with an abbreviated form such as "autoeval" for normal use). I don't see how we can guarantee order of evaluation without syntax for late binding of parameters. I think the predictability is a potentially valuable aspect of Chris's proposal that might justify special syntax for late-bound defaults of formal arguments.[1]
Indeed. But here's the question: If a deferred object is to be a replacement for default_factory, then it must by definition be able to be stored for later. So it can't be autoevaluated unless there's some mechanism for delaying the autoevaluation. This seems like an incredibly messy approach. The use-cases for deferred evaluation differ based on whether you need it to be evaluated once or multiple times, whether you want names to be looked up in the caller's or the callee's context, etc, etc, etc. What would have overlap with argument defaults isn't the same thing that would be useful for dataclasses. So there would need to be multiple variants, or multiple ways to use them. ChrisA