On Fri, Dec 10, 2021 at 7:54 PM Eric V. Smith <e...@trueblade.com> wrote:

> Not sure if you meant this to go to the list or not.
>
I did — ( I know it seems to be the consensus, but I really think respond
to list should be the default…)

Moving on…

On 12/10/2021 7:50 PM, Christopher Barker wrote:
>
> Thanks Eric, this is a great example, thanks.
>
> It does raise some questions. Though.
>
> If we could use any expression as a deferred expression, then we still
> have the two key questions:
>
> When does it get evaluated, and what namespaces does it use?
>
> I agree those are good questions. I think, like PEP 671, it would get
> evaluated at the start of the function (in this case, __init__). It's
> easier for dataclasses, because I could just force the evaluation there.
> But for normal function arguments, maybe we'd have to say that before the
> function starts executing, any arguments which are deferred objects
> automatically are evaluated. And I think the namespace would be where it's
> defined.
>
Ahh, then that would make them less useful for default parameters— even for
the dataclass case. It would work fine if you used only builtins (or
literals) but that’s about it. So Chris’ canonical example of n =>
len(input_list) wouldn’t work.

Which is why I think that if there were a general purpose deferred object,
we’d need special syntax or rules for when used as late-bound defaults.

I'll admit I haven't thought all of this through in enough detail to
> implement it. I'm just trying to point out that we could use the general
> concept in other places.
>
Which is exactly what I asked for — thanks! I think this is a really
interesting use case, not so much as it’s a general purpose deferred
object, but because it’s about how to do/use late-bound defaults in meta
programming.


> def fun(n):
>     return `len(n)`
>
> @dataclasses.dataclass
> class A:
>     length: n = fun()
>
> What would that put in the signature? What namespace would the express e
> evaluated in?
>
> I think it should be evaluated in the context of "fun". Clearly it would
> need to create a closure.
>

Which would be a potentially useful deferred object, but not a good one for
late-bound defaults.

Here’s a new (not well thought out) idea:

@dataclasses.dataclass
class A:
    Input_list: list
    length: int => len(input_list)

So length gets set to a “late bound default expression” that Is an actual
value. It would have to store the expression itself, probably as a string,
and it would get evaluated in the namespace of the function, when the
function was called. So the generated __init__ would be the same as:

def __init__(self, input_list, length=>len(input_list):

And you could also do:

get_length => len(input_list)

@dataclasses.dataclass
class A:
    Input_list: list
    length: int = get_length

Not that that would be a good idea.

This suggestion would mean that “=>” would create a deferred expression,
but it would not be a general purpose one.

Though maybe there could be a way to evaluate it in a more general way,
kind of like eval — where you can control the namespaces used.

I guess what I’m suggesting is that we could create a very specific kind of
deferred object, and in the future expand it to more general use. Rather
than the general case rendering the late-bound default concept.

-CHB

> --
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
_______________________________________________
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/7PYISXVUZMK2A7VUPNYU4Q2QD6JJEEUC/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to