<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>On May 23, 2011, at 9:04 AM, Kam Kasravi wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div bgcolor="#FFFFFF"><div>In the block lambda strawman examples, the surprise </div><div>is the use of return (and other goto constructs like break). At least in similar discussions related </div><div>to closures in java, Neal Grafter</div></div></blockquote><div><br></div>(Gafter)</div><div><br></div><div><br><blockquote type="cite"><div bgcolor="#FFFFFF"><div>suggests that return and other control constructs not be allowed (<a href="http://gafter.blogspot.com/2006/08/tennents-correspondence-principle-and.html">http://gafter.blogspot.com/2006/08/tennents-correspondence-principle-and.html</a>) due to TCP.</div></div></blockquote><div><br></div>That's not quite a solution: you can indeed then factor out the guts of a closure immediately or downward-funarg-ly (sic) invoked -- but you can't factor code the other direction without losing expressiveness at the statement level.</div><div><br></div><div><br><blockquote type="cite"><div bgcolor="#FFFFFF"><div> I assume this is also why var is being excluded in the strawman.</div></div></blockquote><div><br></div>No, var is worse because it hoists to top of function body. Strictly different and harder compared to break/continue loop/switch targeting (which falls out for free with proper Completion type usage), and also compared to return (no hoisting).</div><div><br></div><div><br><blockquote type="cite"><div bgcolor="#FFFFFF"><div> Given the impact to the grammar to exclude var,</div></div></blockquote><div><br></div>Trivial. Can be done a la the "NoIn" productions but better if we do it with prose. Not a big deal, IMHO.</div><div><br></div><div><br><blockquote type="cite"><div bgcolor="#FFFFFF"><div>would this constraint be compile time checked?</div></div></blockquote><div><br></div>Yes, |var| would be forbidden in block-lambdas by early error.</div><div><br></div><div><br><blockquote type="cite"><div bgcolor="#FFFFFF"><div> Would grammar  constraints like no var be semantically checked by implementors or folded into the grammar formally?</div></div></blockquote><div><br></div>See above; not a big deal, up to specificiers.</div><div><br></div><div><br><blockquote type="cite"><div bgcolor="#FFFFFF"><div> The latter would suggest a production rule other than StatementList*, where VariableStatement would be excluded...</div></div></blockquote><div><br></div>That's too duplicative. The NoIn productions are too. We could have parameterized productions, or use prose. This is a sideshow, though.</div><div><br></div><div>I don't agree with banning control statements in blocks, in any event.</div><div><br></div><div>/be</div><div><br><blockquote type="cite"><div bgcolor="#FFFFFF"><div><br>On May 23, 2011, at 6:57 AM, Brendan Eich <<a href="mailto:brendan@mozilla.com">brendan@mozilla.com</a>> wrote:<br><br></div><div></div><blockquote type="cite"><div><div><div>On May 22, 2011, at 10:15 PM, Kam Kasravi wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div><div style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); font-family: 'times new roman', 'new york', times, serif; font-size: 12pt; position: static; z-index: auto; "><div>Is this valid?</div><div><br></div><div>function Person(a) {</div><div>  this.age = a;</div><div>}</div><div>Person.prototype.myage = {|| this.age};</div></div></div></blockquote><div><br></div>Block-lambda, per Tennent's Correspondence Principle as cited, uses the same <font class="Apple-style-span" face="Courier">this</font> as if you moved the code inside the <font class="Apple-style-span" face="Courier">{|| </font><i>...</i><font class="Apple-style-span" face="Courier"> }</font> outside. This is so <i>expr</i> is equivalent to <font class="Apple-style-span" face="Courier">{|| </font><i>expr</i> <font class="Apple-style-span" face="Courier">}()</font>. JS hackers do not see <font class="Apple-style-span" face="Courier">function () { </font><i>...</i><font class="Apple-style-span" face="Courier"> }</font> so should not expect <font class="Apple-style-span" face="Courier">this</font> to change meaning.</div><div><br></div><div>(For this reason among others, block-lambdas have no [[Construct]] internal method. Same as for built-in functions in ES1-5.)</div><div><br></div><div>So this is not going to do what you want below:</div><div><br></div><div><blockquote type="cite"><div><div style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); font-family: 'times new roman', 'new york', times, serif; font-size: 12pt; position: static; z-index: auto; "><div>function info(myage) {</div><div>  console.log('my age is '+myage());   </div><div>}</div><div>info(new Person(10).myage);</div><div>info(new Person(12).myage);</div></div></div></blockquote><div><br></div>Enclosing the block-lambda within the constructor works:</div><div><br></div><div><div><div style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); font-family: 'times new roman', 'new york', times, serif; font-size: 12pt; position: static; z-index: auto; "><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">function Person(a) {</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">  this.age = a;</span></font></div><div><div><div style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); position: static; z-index: auto; "><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">  this.myage = {|| this.age};</span></font></div></div></div><div><div><div style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); position: static; z-index: auto; "></div></div></div></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">}</span></font></div><div><br></div></div></div><div><div><div style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); font-family: 'times new roman', 'new york', times, serif; font-size: 12pt; position: static; z-index: auto; "><div><span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; ">Note that in this case, unlike the case with a function expression instead of the block-lambda, the implementation can optimize aggressively: no other </span><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">this</span></font><span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; "> can be bound dynamically in any subsequent call via </span><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">new Person(10).myage() </span></font><span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; ">or </span><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">myage()</span></font><span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; "> in </span><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">info</span></font><span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; ">. This is a stronger guarantee than if </span><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">Person</span></font><span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; "> used</span></div><div><span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; "><br></span></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">  this.myage = function () { return this.age; }.bind(this);</span></font></div><div><span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; "><br></span></div><div><font class="Apple-style-span" face="Helvetica"><span class="Apple-style-span" style="font-size: medium;">in the absence of aggressive static analysis (without which, who knows what </span><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">bind</span></font><span class="Apple-style-span" style="font-size: medium;"> means at compile time)?</span></font></div><div><font class="Apple-style-span" face="Helvetica"><span class="Apple-style-span" style="font-size: medium;"><br></span></font></div><div><font class="Apple-style-span" face="Helvetica"><span class="Apple-style-span" style="font-size: medium;">The full closure pattern works too, of course:</span></font></div><div><font class="Apple-style-span" face="Helvetica"><span class="Apple-style-span" style="font-size: medium;"><br></span></font></div><div><font class="Apple-style-span" face="Helvetica"><span class="Apple-style-span" style="font-size: medium;"><div style="font-family: 'times new roman', 'new york', times, serif; font-size: 16px; "><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px; ">function Person(a) {</span></font></div><div style="font-family: 'times new roman', 'new york', times, serif; font-size: 16px; "><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px; ">  return {get age() { return a; }, </span></font><span class="Apple-style-span" style="font-family: Courier; font-size: 12px; ">myage: {|| a}};</span></div><div style="font-family: 'times new roman', 'new york', times, serif; font-size: 16px; "><div><div><div style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); position: static; z-index: auto; "></div></div></div></div><div style="font-family: 'times new roman', 'new york', times, serif; font-size: 16px; "><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px; ">}</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px; "><br></span></font></div></span></font></div><div><font class="Apple-style-span" face="Helvetica"><span class="Apple-style-span" style="font-size: medium;"><br></span></font></div><div><font class="Apple-style-span" face="Helvetica"><span class="Apple-style-span" style="font-size: medium;">but you have to commit to accessors.</span></font></div><div><font class="Apple-style-span" face="Helvetica"><span class="Apple-style-span" style="font-size: medium;"><br></span></font></div><div><font class="Apple-style-span" face="Helvetica"><span class="Apple-style-span" style="font-size: medium;">One last note: freezing and joining (see </span><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">#</span></font><span class="Apple-style-span" style="font-size: medium;"> usage in <a href="http://wiki.ecmascript.org/doku.php?id=strawman:arrow_function_syntax"></a><a href="http://wiki.ecmascript.org/doku.php?id=strawman:arrow_function_syntax">http://wiki.ecmascript.org/doku.php?id=strawman:arrow_function_syntax</a> referencing <a href="http://wiki.ecmascript.org/doku.php?id=strawman:const_functions"></a><a href="http://wiki.ecmascript.org/doku.php?id=strawman:const_functions">http://wiki.ecmascript.org/doku.php?id=strawman:const_functions</a>) do not enable much more optimization in this constructor pattern, however you do it. Whether closing over </span><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">this</span></font><span class="Apple-style-span" style="font-size: medium;"> or the parameter </span><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">a</span></font><span class="Apple-style-span" style="font-size: medium;">, the joined block-lambda (or function) identity cannot join across the </span><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">Person</span></font><span class="Apple-style-span" style="font-size: medium;"> closure boundary.</span></font></div><div><font class="Apple-style-span" face="Helvetica"><span class="Apple-style-span" style="font-size: medium;"><br></span></font></div><div><font class="Apple-style-span" face="Helvetica"><span class="Apple-style-span" style="font-size: medium;">(I did not make block-lambdas implicitly frozen and joined since some on TC39 and in the community object to that kind of change without opt-in syntax, and because it doesn't help much, given the change to make </span><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">this</span></font><span class="Apple-style-span" style="font-size: medium;"> a lexical "upvar".)</span></font></div><div><font class="Apple-style-span" face="Helvetica"><span class="Apple-style-span" style="font-size: medium;"><br></span></font></div><div><span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; ">So block-lambdas are not going to solve the "bound method" cost problem in JS. For that, you need a </span><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">class</span></font><span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; "> proposal that automatically binds methods to the receiver while at the same time disallowing any kind of dynamic inheritance. ES4 after ActionScript 3 had this; Java etc. do too of course.</span></div><div><span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; "><br></span></div><div><span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; ">Does JS really need it, vs. the prototypal function-valued properties as methods pattern? In any event, nothing block-lambdas or any other </span><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">this</span></font><span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; ">-capturing form can fix by themselves.</span></div><div><span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; "><br></span></div><div><span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; ">/be</span></div></div></div></div></div><div><br></div></div></blockquote></div></blockquote></div><br></body></html>