And my response again, although slightly edited.

On 12/11/2021 11:28 AM, Christopher Barker wrote:
Sorry, accidentally off-list. Here it is again.

On Fri, Dec 10, 2021 at 4:50 PM Christopher Barker <python...@gmail.com> 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. 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.

One thing in particular I haven't thought through: what if you really want to pass in a "deferred object" to a function? Can you keep it from being evaluated? Would you specify that on the caller side, or the callee side?


        @dataclasses.dataclass
        class A:
            my_list: list = dataclasses.field(default_factory=list)

        What I'd like to be able to say:

        @dataclasses.dataclass
        class A:
            my_list: list = `[]`

    I think in the data classes case, you could clearly define both of
    those. But in the general case?

    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.


    Yes, that is completely contrived, but it does bring up the
    complications of a “general” solution.

    Maybe we could solve the dataclass problem with late bound class
    attributes:

    @dataclasses.dataclass
    class A:
        length: n => len(n)

    Though I suppose that would still get evaluated before the
    dataclass decorator would see it :-(

There are absolutely some issues that need thinking through. It's entirely possible the idea can't be made to work. I'm just saying we should think it through and see if it could be made to work before we just say "we only want late-bound things as function parameters, and we can't use them anywhere else". I'm worried that if we only do it for function parameters, we might need to change the syntax (and I guess possibly the semantics) in the future in order to support other uses for deferred objects.


    Side note: I wonder if dataclasses could be a bit smarter for the
    common. case: if the type is a callable, and the value is a
    particular Sentinel, the. Call it to get the default:

    @dataclasses.dataclass
    class A:
        my_list: list = dataclasses.Empty

    That would work for most of the cases where I need to use field
    explicitly.

That's an interesting idea.

Eric


    - CHB




        In the class A, before @dataclass is called, I want A.my_list
        to be a "deferred object" that I could then use when
        @dataclass is generating __init__(). Exactly how and when the
        "deferred object" would get evaluated is debatable, but not
        so important for the sake of this discussion. Suffice it to
        say that it would either be explicitly or implicitly
        evaluated at the start of __init__.

        I think you can see that this would benefit from similar
        functionality to late-bound parameters, and that if we had
        this more general mechanism that late-bound parameters could
        use the same underlying mechanism.

        And in case I wasn't clear: to get the late-bound parameter
        functionality using this syntax, you'd use:

        def foo(my_list = `[]`):

        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. And that's why I thing
        not restricting it to a function-definition-only syntax is
        important: we should produce a syntax that can be used in more
        places than just functions. This is why I think we need to
        decide on this larger scope before accepting the narrow
        function-definition-only syntax: if we decide to add "deferred
        objects" later, we'd have two ways to specify late-bound
        parameters [0].

        Eric

        [0]: Or arguments, I can never remember which is which:
        someone needs to invent a memorable mnemonic device.

        Had these "deferred objects" existed when I designed
        dataclasses, I would have used them instead of the clunky
        default_factory. PEP 671 does not help with this use case,
        where a late-bound parameter isn't specified in a function
        definition. I need the late-bound parameter to be stored in
        an object I can refer to later.

        Eric

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

-- Christopher Barker, PhD (Chris)

    Python Language Consulting
      - Teaching
      - Scientific Software Development
      - Desktop GUI and Web Development
      - wxPython, numpy, scipy, Cython

--
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 topython-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived 
athttps://mail.python.org/archives/list/python-ideas@python.org/message/IDKDVY4LNNB2WLQVS6QM3OZX6C6QXE7Y/
Code of Conduct:http://python.org/psf/codeofconduct/
_______________________________________________
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/6RMO665EXTDVHHF6MIKDHJJGIKNERK2Z/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to