<div dir="ltr">I think maybe the idiomatic pattern should be assignment rather than just bare name.  E.g.<div><br></div><div><blockquote style="font-size:11.2px;margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><font face="monospace, monospace">f = delayed 1 + 2</font></div></div></blockquote><blockquote style="font-size:11.2px;margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><font face="monospace, monospace"># We want to evaluate f before next op for some reason</font></div></div></blockquote><blockquote style="font-size:11.2px;margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><font face="monospace, monospace"><b>f = f</b></font></div></div></blockquote><blockquote style="font-size:11.2px;margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><font face="monospace, monospace"># f is already a concrete value now, before calculating g</font></div></div></blockquote><blockquote style="font-size:11.2px;margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><font face="monospace, monospace">g = f * 7</font></div></div></blockquote></div><div><br></div><div>I think if we follow my rule that <font face="arial, helvetica, sans-serif">"<span style="font-size:11.2px">everything lazy within delayed expression stays unevaluated" that needs to apply to function calls too.  So I think in:</span></font></div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><span style="font-size:11.2px"><font face="monospace, monospace">x = delayed my_lazy_func(b, c)</font></span></div></blockquote><div><span style="font-size:11.2px"><br></span></div><div><span style="font-size:11.2px">This would not affect the laziness of 'b' or 'c' with that line.  It also would not run any flow control within the function, etc.  Basically, it's almost like wrapping it in a lambda:</span></div><div><span style="font-size:11.2px"><br></span></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><span style="font-size:11.2px"><font face="monospace, monospace">x = lambda: my_lazy_func(b, c)</font></span></blockquote></div><div><span style="font-size:11.2px"><font face="monospace, monospace"><br></font></span></div><div><span style="font-size:11.2px"><font face="arial, helvetica, sans-serif">Except that when you finally <b>do</b> want the value out of 'x' you don't spell that as 'x() + 7' but simply as 'x + 7'.</font></span></div><div><span style="font-size:11.2px"><font face="arial, helvetica, sans-serif"><br></font></span></div><div><span style="font-size:11.2px"><font face="arial, helvetica, sans-serif">This also means that the above delayed function call would be functionally identical if you spelled it:</font></span></div><div><span style="font-size:11.2px"><font face="arial, helvetica, sans-serif"><br></font></span></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><span style="font-size:11.2px"><font face="monospace, monospace">x = delayed my_lazy_func(delayed b, delayed c)</font></span></blockquote></div><div><span style="font-size:11.2px"><font face="arial, helvetica, sans-serif"><br></font></span></div><div><span style="font-size:11.2px"><font face="arial, helvetica, sans-serif">This also means that a 'delayed' object needs to be idempotent.  So</font></span></div><div><span style="font-size:11.2px"><font face="arial, helvetica, sans-serif"><br></font></span></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><span style="font-size:11.2px"><font face="monospace, monospace">x = delayed 2+2</font></span></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><span style="font-size:11.2px"><font face="monospace, monospace">y = delayed x</font></span></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><span style="font-size:11.2px"><font face="monospace, monospace">z = delayed delayed delayed y</font></span></div></blockquote><font face="arial, helvetica, sans-serif"><span style="font-size:11.2px"><br></span></font><div><font face="arial, helvetica, sans-serif"><span style="font-size:11.2px">Wrapping more delays around an existing delayed object should probably just keep the same object rather than "doubly delaying" it.  If there is some reason to create separate delayed objects that isn't occurring to me, evaluating 'z' would still go through the multiple evaluation levels until it got to a non-delayed value.</span></font></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Feb 16, 2017 at 10:55 PM, David Mertz <span dir="ltr"><<a href="mailto:mertz@gnosis.cx" target="_blank">mertz@gnosis.cx</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="">On Thu, Feb 16, 2017 at 10:33 PM, Joshua Morton <span dir="ltr"><<a href="mailto:joshua.morton13@gmail.com" target="_blank">joshua.morton13@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">David, can you elaborate on your example?<div><br></div><div>if we replaced line four with</div><div><br></div><div>    >>> x = my_lazy_func(b, delayed c)</div><div><br></div><div>what would the value of `x` be, and how would this differ from either</div></div></blockquote><div><br></div></span><div>The value of the function would be whatever you want, including another delayed object, potentially.</div><div><br></div><div>Here's a toy function just to show the pattern I have in mind:</div><div><br></div></div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">def my_lazy_func(x, y):</font></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">    if x == 0:</font></div><div><span style="font-family:monospace,monospace">        # evaluate y if it was lazy, or just return plain value</span><font face="monospace, monospace"><br></font></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">        return y  </font></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">    elif x > 0:</font></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">        # create a lazy object whether y was lazy or concrete</font></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">        # if y *was* lazy, it remains so in delayed expression</font></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">        return delayed y + 17</font></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">    elif x < -10:</font></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">        # evaluate y, if delayed, by virtue of being part of</font></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">        # plain non-delayed RHS expression</font></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">        z = y * 6</font></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">        return z</font></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">    else:</font></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">        # y never mentioned, so if it was lazy nothing changes</font></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">        return x - 22</font></div></div></div></blockquote><font face="arial, helvetica, sans-serif"><div><font face="arial, helvetica, sans-serif"><br></font></div>Whether or not 'c' (called 'y' within the function scope) gets evaluated/computed depends on which branch was taken within the function.  Once the delayed computation is done, the object at the delayed address becomes concrete thereafter to avoid repeated (and potentially stateful or side-effect causing evaluation).</font><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">One question is whether you'd need to write:</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><font face="monospace, monospace">m = delayed 1 + 2<br>n = delayed m * 3<br># This seems ugly and unnecessary (but should work)<br>q = delayed m / delayed n<br># This seems better (does not evaluate m or n)<br># everything lazy within delayed expression stays unevaluated</font></blockquote><div><div class="gmail_extra"><div class="gmail_quote"><div>            <font face="monospace, monospace">q2 = delayed m/n</font></div><div><br></div><div>If you ever need to explicitly evaluate a delayed object, it is as simple as putting a name pointing to it on a line by itself:</div><div><br></div></div></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">f = delayed 1 + 2</font></div></div></div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace"># We want to evaluate f before next op for some reason</font></div></div></div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">f</font></div></div></div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace"># f is already a concrete value now, before calculating g</font></div></div></div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">g = f * 7</font></div></div></div></div></blockquote><div><div class="gmail_extra"><div><div class="h5"><div class="gmail_quote"><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="m_-4967849575601980640gmail-HOEnZb"><div class="m_-4967849575601980640gmail-h5"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><div style="font-family:monospace,monospace" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><span style="font-family:arial,helvetica,sans-serif">So for example, in a hypothetical Python 3.7+:</span><br></div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><font face="arial, helvetica, sans-serif" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></font></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><font face="arial, helvetica, sans-serif" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">>>> a = delayed 1 + 2</font></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><font face="arial, helvetica, sans-serif" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">>>> b = delayed b * 3</font></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><font face="arial, helvetica, sans-serif" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">>>> c = delayed 12/3</font></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><font face="arial, helvetica, sans-serif" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">>>> my_lazy_func(b, delayed c) # evaluates b but not yet c<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">>>> b<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">9<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">>>> delayed c<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><delayed object at 0x123456789></font></blockquote><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><font face="monospace, monospace" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></font></div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><font face="arial, helvetica, sans-serif" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">If you want to do something like Dask... or for Dask itself to be able to use it in some eventual version, you'd need to be able to keep objects from evaluating even while you passed them around.  The obvious use is for finding parallelism, but other things like passing callbacks might find this useful too.</font></div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><font face="arial, helvetica, sans-serif" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></font></div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><font face="arial, helvetica, sans-serif" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">Dask delayed objects stay lazy until you explicitly `.compute()` on them (which does so recursively on every lazy object that might go into the computation).  This hypothetical new keyword would have object evaluate eagerly <b class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">unless</b> you explicitly kept them lazy.  But the idea is that the programmer would still get to decide in their code.<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></font></div></div><div dir="ltr" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><div dir="auto" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><font face="monospace, monospace" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></font></div></div></blockquote><div class="gmail_extra m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><div class="gmail_quote m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">On Feb 16, 2017 9:53 PM, "Joseph Jevnik" <<a href="mailto:joejev@gmail.com" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" target="_blank">joejev@gmail.com</a>> wrote:<br type="attribution" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><blockquote class="gmail_quote m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">You might be interested in <a href="https://github.com/llllllllll/lazy_python" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" target="_blank">https://github.com/llllllllll/<wbr>lazy_python</a>, which implements the features you describe but instead of a keyword it uses a decorator.<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></div><div class="gmail_extra m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><div class="gmail_quote m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">On Fri, Feb 17, 2017 at 12:24 AM, Joseph Hackman <span dir="ltr" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><<a href="mailto:josephhackman@gmail.com" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" target="_blank">josephhackman@gmail.com</a>></span> wrote:<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><blockquote class="gmail_quote m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">Howdy All!<div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">This suggestion is inspired by the question on "Efficient debug logging".</div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"> <br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></div></div></blockquote></div></div></blockquote><blockquote class="gmail_quote m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="gmail_extra m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><div class="gmail_quote m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><blockquote class="gmail_quote m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">I propose a keyword to mark an expression for delayed/lazy execution, for the purposes of standardizing such behavior across the language.</div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">The proposed format is:<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">delayed: <expr></div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">i.e. <a href="http://log.info" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" target="_blank">log.info</a>("info is %s", delayed: expensiveFunction())</div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">Unlike 'lambda' which returns a function (so the receiver must be lambda-aware), delayed execution blocks are for all purposes values. The first time the value (rather than location) is read, or any method on the delayed object is called, the expression is executed and the delayed expression is replaced with the result. (Thus, the delayed expression is only every evaluated once).</div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">Ideally:</div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">a = delayed: 1+2</div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">b = a</div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">print(a) #adds 1 and 2, prints 3</div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"># a and b are now both just 3</div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">print(b) #just prints 3</div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">Mechanically, this would be similar to the following:</div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><pre style="background-color:rgb(43,43,43);color:rgb(169,183,198);font-family:"courier new";font-size:9pt" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><span style="color:rgb(204,120,50);font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">class </span><span style="font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">Delayed</span>():<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">    <span style="color:rgb(204,120,50);font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">def </span><span style="color:rgb(178,0,178)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">__init__</span>(<span style="color:rgb(148,85,141)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">self</span><span style="color:rgb(204,120,50)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">, </span>func):<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">        <span style="color:rgb(148,85,141)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">self</span>.__func = func<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">        <span style="color:rgb(148,85,141)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">self</span>.__executed = <span style="color:rgb(204,120,50);font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">False<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></span><span style="color:rgb(204,120,50);font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">        </span><span style="color:rgb(148,85,141)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">self</span>.__value = <span style="color:rgb(204,120,50);font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">None<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></span><span style="color:rgb(204,120,50);font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></span><span style="color:rgb(204,120,50);font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">    def </span><span style="color:rgb(178,0,178)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">__str__</span>(<span style="color:rgb(148,85,141)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">self</span>):<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">        <span style="color:rgb(204,120,50);font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">if </span><span style="color:rgb(148,85,141)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">self</span>.__executed:<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">            <span style="color:rgb(204,120,50);font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">return </span><span style="color:rgb(148,85,141)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">self</span>.__value.<span style="color:rgb(178,0,178)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">__str__</span>()<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">        <span style="color:rgb(148,85,141)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">self</span>.__value = <span style="color:rgb(148,85,141)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">self</span>.__func()<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">        <span style="color:rgb(148,85,141)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">self</span>.__executed = <span style="color:rgb(204,120,50);font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">True<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></span><span style="color:rgb(204,120,50);font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">        return </span><span style="color:rgb(148,85,141)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">self</span>.__value.<span style="color:rgb(178,0,178)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">__str__</span>()<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><span style="color:rgb(204,120,50);font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">def </span><span style="font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">function_print</span>(value):<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">    <span style="color:rgb(136,136,198)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">print</span>(<span style="color:rgb(0,128,128)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">'function_print'</span>)<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">    <span style="color:rgb(136,136,198)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">print</span>(value)<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><span style="color:rgb(204,120,50);font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">def </span><span style="font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">function_return_stuff</span>(value):<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">    <span style="color:rgb(136,136,198)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">print</span>(<span style="color:rgb(0,128,128)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">'function_return_stuff'</span>)<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">    <span style="color:rgb(204,120,50);font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">return </span>value<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">function_print(function_return<wbr>_stuff(<span style="color:rgb(0,128,128)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">'no_delay'</span>))<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">function_print(Delayed(<span style="color:rgb(204,120,50);font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">lambda</span>: function_return_stuff(<span style="color:rgb(0,128,128)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">'delayed<wbr>'</span>)))<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">delayed = Delayed(<span style="color:rgb(204,120,50);font-weight:bold" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">lambda</span>: function_return_stuff(<span style="color:rgb(0,128,128)" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">'delayed<wbr>_object'</span>))<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">function_print(delayed)<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">function_print(delayed)</pre></div><div class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">Unfortunately, due to <a href="https://docs.python.org/3/reference/datamodel.html#special-lookup" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" target="_blank">https://docs.python.org/3/r<wbr>eference/datamodel.html#specia<wbr>l-lookup</a> , this magic delayed class would need to implement many magic methods, as __getattribute__ is not _always_ called.</div></div>
<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">______________________________<wbr>_________________<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">
Python-ideas mailing list<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">
<a href="mailto:Python-ideas@python.org" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" target="_blank">Python-ideas@python.org</a><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" target="_blank">https://mail.python.org/mailma<wbr>n/listinfo/python-ideas</a><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" target="_blank">http://python.org/psf/codeofco<wbr>nduct/</a><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></blockquote></div><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></div>
<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">______________________________<wbr>_________________<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">
Python-ideas mailing list<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">
<a href="mailto:Python-ideas@python.org" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" target="_blank">Python-ideas@python.org</a><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" target="_blank">https://mail.python.org/mailma<wbr>n/listinfo/python-ideas</a><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" target="_blank">http://python.org/psf/codeofco<wbr>nduct/</a><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg"></blockquote></div></div>
</div></div>
______________________________<wbr>_________________<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">
Python-ideas mailing list<br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">
<a href="mailto:Python-ideas@python.org" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" target="_blank">Python-ideas@python.org</a><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" target="_blank">https://mail.python.org/mailma<wbr>n/listinfo/python-ideas</a><br class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg">
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer" class="m_-4967849575601980640gmail-m_8841340453778310431gmail_msg" target="_blank">http://python.org/psf/codeofco<wbr>nduct/</a></blockquote></div>
</div></div></blockquote></div><br><br clear="all"><div><br></div></div></div><span class="HOEnZb"><font color="#888888">-- <br><div class="m_-4967849575601980640gmail_signature">Keeping medicines from the bloodstreams of the sick; food <br>from the bellies of the hungry; books from the hands of the <br>uneducated; technology from the underdeveloped; and putting <br>advocates of freedom in prisons.  Intellectual property is<br>to the 21st century what the slave trade was to the 16th.<br></div>
</font></span></div></div></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">Keeping medicines from the bloodstreams of the sick; food <br>from the bellies of the hungry; books from the hands of the <br>uneducated; technology from the underdeveloped; and putting <br>advocates of freedom in prisons.  Intellectual property is<br>to the 21st century what the slave trade was to the 16th.<br></div>
</div>