On Wed, Jun 22, 2022 at 02:30:14PM -0400, David Mertz, Ph.D. wrote:
The difference is in composition of operations. I can write a dozen zero-argument lambdas easily enough. But those are all isolated. But basically, think about `x = (later expensive1() + later expensive2()) / later expensive3()`. How can we make `x` itself be a zero argument lambda? [... see below ...]
The following three constructions are roughly equivalent: # Using proposed PEP x = (later expensive1() + later expensive2()) / later expensive3() x.compute() # Using zero-argument nested lambdas x = lambda: ((lambda: expensive1())() + (lambda: expensive2())()) / (lambda: expensive3())() x() # compute # Using the good old function def x(): return (expensive1() + expensive2()) / expensive3() x() # compute
[... cont ...] And not just with those exact operations on the Deferreds, but arbitrary combinations of Deferreds to create more complex Deferreds, without performing the intermediate computations?
Perhaps this is the real focus to analyze. The PEP suggests that x.compute() does something *fundamentally* different from just executing the intermediate expressions. The *key* difference between the PEP proposal and the use of zero-argument lambdas or good-old functions is that no intermediate expression is computed (expensive1, expensive2 and expensive3 separately) but the whole combined expression is computed by *xxx* allowing it to perform *yyy*. Having said that, I want to remark the "xxx" and "yyy" above are missing from the PEP. The PEP does not explain who nor how these deferred computations are really executed (the xxx and yyy). As I mentioned in my previous email, the PEP gives an example about how Dask uses deferred expression to build and distribute complex arithmetic/statistics operations over a partitioned dataframe but this example cannot be used to assume that Python will do it in the same way. In my previous email I mentioned others libs that implement deferred expressions and "should" benefit from the PEP however I cannot see it how. Perhaps a concrete example borrowed from selectq could spot the missing pieces (xxx and yyy): # from selectq red_divs = sQ.select("div", class_="red") # this is deferred blue_divs = sQ.select("div", class_="blue") # this is deferred both = red_divs | blue_divs # this is deferred count = both.count() # the count() forces the real computation Now, I imagine rewriting it using PEP but.... # using PEP red_divs = later sQ.select("div", class_="red") blue_divs = later sQ.select("div", class_="blue") both = later (red_divs | blue_divs) count = later both.count() count = count.compute() ...but how does know the Python VM what "compute()" means or how to do it? (the yyy). Is the Python VM who should do it? (the xxx) I would assume that it is not the Python VM but the library... - how the library will know what compute() means? - how will know about the intermediate red_divs and blue_divs? - what benefits would bring this PEP to libs like PySpark, selectq and Django's ORM (to mention a few)? So far the PEP *does not* explain that and it only talks about how to delay plain python code. In this sense then, I would *agree* with Eric Smith. David may have a different intention, but in the current form the PEP is equivalent to zero-argument lambdas. Thanks, Martin. On Wed, Jun 22, 2022 at 02:30:14PM -0400, David Mertz, Ph.D. wrote:
On Wed, Jun 22, 2022 at 2:17 PM Eric V. Smith <eric@trueblade.com> wrote:
Every time I’ve looked at this, I come back to: other than the clunky syntax, how is explicit evaluation different from a zero-argument lambda?
I've enhanced the PEP, so maybe look at the link for some of my updates; but I need to add a bunch more, so don't want to repost each small draft change.
But basically, think about `x = (later expensive1() + later expensive2()) / later expensive3()`. How can we make `x` itself be a zero argument lambda? And not just with those exact operations on the Deferreds, but arbitrary combinations of Deferreds to create more complex Deferreds, without performing the intermediate computations?
-- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@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/Y6LVDC... Code of Conduct: http://python.org/psf/codeofconduct/