<div dir="ltr">Howdy All!<div><br></div><div>This suggestion is inspired by the question on "Efficient debug logging".</div><div><br></div><div>I propose a keyword to mark an expression for delayed/lazy execution, for the purposes of standardizing such behavior across the language.</div><div><br></div><div>The proposed format is:<br>delayed: <expr></div><div>i.e. <a href="http://log.info">log.info</a>("info is %s", delayed: expensiveFunction())</div><div><br></div><div>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><br></div><div>Ideally:</div><div>a = delayed: 1+2</div><div>b = a</div><div>print(a) #adds 1 and 2, prints 3</div><div># a and b are now both just 3</div><div>print(b) #just prints 3</div><div><br></div><div>Mechanically, this would be similar to the following:</div><div><pre style="background-color:rgb(43,43,43);color:rgb(169,183,198);font-family:"courier new";font-size:9pt"><span style="color:rgb(204,120,50);font-weight:bold">class </span><span style="font-weight:bold">Delayed</span>():<br>    <span style="color:rgb(204,120,50);font-weight:bold">def </span><span style="color:rgb(178,0,178)">__init__</span>(<span style="color:rgb(148,85,141)">self</span><span style="color:rgb(204,120,50)">, </span>func):<br>        <span style="color:rgb(148,85,141)">self</span>.__func = func<br>        <span style="color:rgb(148,85,141)">self</span>.__executed = <span style="color:rgb(204,120,50);font-weight:bold">False<br></span><span style="color:rgb(204,120,50);font-weight:bold">        </span><span style="color:rgb(148,85,141)">self</span>.__value = <span style="color:rgb(204,120,50);font-weight:bold">None<br></span><span style="color:rgb(204,120,50);font-weight:bold"><br></span><span style="color:rgb(204,120,50);font-weight:bold">    def </span><span style="color:rgb(178,0,178)">__str__</span>(<span style="color:rgb(148,85,141)">self</span>):<br>        <span style="color:rgb(204,120,50);font-weight:bold">if </span><span style="color:rgb(148,85,141)">self</span>.__executed:<br>            <span style="color:rgb(204,120,50);font-weight:bold">return </span><span style="color:rgb(148,85,141)">self</span>.__value.<span style="color:rgb(178,0,178)">__str__</span>()<br>        <span style="color:rgb(148,85,141)">self</span>.__value = <span style="color:rgb(148,85,141)">self</span>.__func()<br>        <span style="color:rgb(148,85,141)">self</span>.__executed = <span style="color:rgb(204,120,50);font-weight:bold">True<br></span><span style="color:rgb(204,120,50);font-weight:bold">        return </span><span style="color:rgb(148,85,141)">self</span>.__value.<span style="color:rgb(178,0,178)">__str__</span>()<br><br><br><span style="color:rgb(204,120,50);font-weight:bold">def </span><span style="font-weight:bold">function_print</span>(value):<br>    <span style="color:rgb(136,136,198)">print</span>(<span style="color:rgb(0,128,128)">'function_print'</span>)<br>    <span style="color:rgb(136,136,198)">print</span>(value)<br><br><span style="color:rgb(204,120,50);font-weight:bold">def </span><span style="font-weight:bold">function_return_stuff</span>(value):<br>    <span style="color:rgb(136,136,198)">print</span>(<span style="color:rgb(0,128,128)">'function_return_stuff'</span>)<br>    <span style="color:rgb(204,120,50);font-weight:bold">return </span>value<br><br>function_print(function_return_stuff(<span style="color:rgb(0,128,128)">'no_delay'</span>))<br><br>function_print(Delayed(<span style="color:rgb(204,120,50);font-weight:bold">lambda</span>: function_return_stuff(<span style="color:rgb(0,128,128)">'delayed'</span>)))<br><br>delayed = Delayed(<span style="color:rgb(204,120,50);font-weight:bold">lambda</span>: function_return_stuff(<span style="color:rgb(0,128,128)">'delayed_object'</span>))<br>function_print(delayed)<br>function_print(delayed)</pre></div><div>Unfortunately, due to¬†<a href="https://docs.python.org/3/reference/datamodel.html#special-lookup">https://docs.python.org/3/reference/datamodel.html#special-lookup</a> , this magic delayed class would need to implement many magic methods, as __getattribute__ is not _always_ called.</div></div>