On Sun, Oct 31, 2021 at 2:52 PM David Mertz, Ph.D.
<david.me...@gmail.com> wrote:
>
>
> On Sat, Oct 30, 2021, 11:03 PM Chris Angelico
>>
>> That's if you were to create a deferred *type*. An object which can be 
>> evaluated later. My proposal is NOT doing that, because there is no object 
>> that represents the unevaluated expression. You can't pull that expression 
>> out and evaluate it somewhere else. It wouldn't be meaningful.
>
>
> Put this way, I admit it is intelligible. Maybe it even reduces the order of 
> magnitude of my opposition to it.
>
> What you are trying to create remains a "unit of computation" even though it 
> is not itself a Python object. As Brendan points out, this is a fundamental 
> change to Python's object model.
>
> It amounts to saying "I want to perform some computation within the body of a 
> function, but I don't want to WRITE it in the body of a function." That feels 
> like an anti-goal to me.
>

Not quite; I want to perform it within the *context* of the function,
but not in the body. A function's context (its scope, available
variables, etc, etc, etc) is where most of its body is executed, but
for example, a list comprehension is part of the function's body while
not being in the same context (it's in a subcontext defined by a
nested function).

> I suppose I don't *hate* something like this, which can be done with no 
> syntax change:
>
> @rewrite
> def foo(a, size=Late("len(a)")):
>     print("The list is length", size)
>
> In the functions I actually use and write, the problem all of this is trying 
> to solve is either trivial or irrelevant.
>

Thing is, that can't actually be done, because there's no way to make
that able to see the function's parameters without some VERY weird
shenanigans. You'd have to completely recreate the
argument-to-parameter allocation, apply all preceding defaults, and
then have a set of locals which can be passed to eval(); and then
having done all that, deconstruct your locals into *a,**kw to pass
back to the original function. Meanwhile, you have to capture any
nonlocals, in case len isn't actually a global.

In contrast, having this as a compiler construct is simple: In the
context of the function, if the parameter hasn't been given a value,
evaluate the expression and assign.

(Side point: The current reference implementation allows assignment
expressions inside default argument expressions, mainly because I
didn't go to the effort of blocking them. But if you ever ACTUALLY do
this, then..... *wat*)

> In libraries like Pandas, for example, there are often tens of arguments with 
> defaults of None... But it is rarely a single default to resolve. Rather, 
> there is complex logic about the interaction of which arguments are provided 
> or absent, leading to numerous code paths to configure the actual behavior of 
> a call.
>
> For these, the logic of missing arguments must live in the body, where it 
> naturally belongs.
>

There will always be cases too complicated for simple default
expressions, just as there are already cases too complicated for
simple default values. They will continue to be handled by the body of
the function, as they currently are. This proposal isn't a replacement
for all argument processing.

ChrisA
_______________________________________________
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/4RRWHFOJRF26S54MDSXO3WH4I3OVYT7I/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to