
On Wed, 22 Jun 2022 at 08:21, Carl Meyer via Python-ideas python-ideas@python.org wrote:
On Tue, Jun 21, 2022 at 4:10 PM David Mertz, Ph.D. david.mertz@gmail.com wrote:
On Tue, Jun 21, 2022 at 5:53 PM Brendan Barnwell brenbarn@brenbarn.net wrote:
In the example, we assume that the built-in function `type()` is special in not counting as a reference to the binding for purpose of realizing a computation. Alternately, some new special function like `isdeferred()` might be used to check for ``Deferred`` objects.
I'll have to ponder my thoughts about the proposal as a whole, but this particular aspect seems dubious to me. As I understand it this would require some fairly deep changes to how evaluation works in Python. Right now in an expression like `type(blah)`, there isn't any way for the evaluation of `blah` to depend on the fact that it happens to occur as an argument to `type`.
I absolutely agree that this is a sore point in my first draft. I could shift the magic from `type()` to `isdeferred()`, but that doesn't really change anything for your examples. I suppose, that is, unless `isdeferred()` becomes something other than a real function, but more like some sort of macro. That doesn't make me happy either.
However, I *would* like to be able to answer the question "Is this object a DeferredObject?" somehow. For example, I'd like some way to write code similar to:
if isdeferred(expensive_result): log.debug("The computationally expensive result is not worth calculating here") else: log.debug(f"We already hit a path that needed the result, and it is {expensive_result}")
Any thoughts on what might be the least ugly way to get that?
I think all it really requires is for isdeferred() to be a builtin implemented in C rather than Python. It will be much better IMO to have isdeferred() returning a bool and not have any deferred object/type visible to Python.
It would have to be non-assignable and probably a keyword. Otherwise, the exact same issues will keep occurring.
What are the scoping rules for deferred objects? Do they access names where they are evaluated, or where they are defined? Consider:
def f(x): spam = 1 print(x)
def g(): spam = 2 f(later spam)
g()
Does this print 1 or 2?
This is a fundamental and crucial point, and must be settled early. You cannot defer this. :)
ChrisA