<div>This post is about my experience with the lookup-by-reference and debug use-cases for Function#name. Both use-cases are very general-purpose--my examples from Ember.js are just representative examples, and illustrate ways that we have worked around existing limitations to provide missing functionality.</div>

<div><br></div><div><b>String References</b></div><div><b><br></b></div><div>Because of the difficulty in managing load order in current JavaScript, as well as a desire to allow for clean dependency injection, we allow many cross-object associations do be defined using Strings. In general, these strings are evaluated the first time the associated object is used at runtime, which allows dependencies to be injected and ensures that all modules to be loaded before references are evaluated.</div>

<div><br></div><div>Here is an example of associations described in Ember Data:</div><div><br></div><div><span style="font-family:'courier new',monospace">App.Person = DS.Model.extend({</span><br></div><div><font face="courier new, monospace">  comments: hasMany('App.Comment')</font></div>

<div><font face="courier new, monospace">});</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">// in another module</font></div><div><font face="courier new, monospace"><br>

</font></div><div><font face="courier new, monospace">App.Comment = DS.Model.extend({</font></div><div><font face="courier new, monospace">  person: belongsTo('App.Person')</font></div><div><font face="courier new, monospace">});</font></div>

<div class="gmail_extra"><br></div><div class="gmail_extra">So how does this sort of thing work? Instead of making <font face="courier new, monospace">App</font><font face="arial, helvetica, sans-serif"> a standard JavaScript object, </font><font face="courier new, monospace">App</font><font face="arial, helvetica, sans-serif"> is an instance of </font><font face="courier new, monospace">Ember.Namespace</font><font face="arial, helvetica, sans-serif">. Once we know its name (which we do by searching on </font><span style="font-family:'courier new',monospace">window</span><font face="arial, helvetica, sans-serif"> for instances of </font><span style="font-family:'courier new',monospace">Ember.Namespace</span><span style="font-family:arial,helvetica,sans-serif">, gross, I know), we can easily resolve String names into actual objects at runtime.</span></div>

<div class="gmail_extra"><span style="font-family:arial,helvetica,sans-serif"><br></span></div><div class="gmail_extra"><span style="font-family:arial,helvetica,sans-serif">This solution, of course, assumes coordination across a global object, which isn't desirable in a world with modules, and the problem may even be fully mitigated in a world with modules. I'm not sure how well modules handle circular dependencies--lazily evaluating strings handles the problem elegantly by deferring evaluation of dependencies until all of the modules have loaded.</span></div>

<div class="gmail_extra"><br></div><div class="gmail_extra">Sencha uses a similar approach for dependencies (see <a href="https://www.sencha.com/learn/how-to-use-classes-in-sencha-touch-2">https://www.sencha.com/learn/how-to-use-classes-in-sencha-touch-2</a>). In particular, Sencha defines and references classes by Strings, avoiding the reference problem. This approach requires the use of a static creation function (<font face="courier new, monospace">Ext.create('Animal', { })</font>), so the String semantics leak into runtime as well.</div>

<div class="gmail_extra"><br></div><div class="gmail_extra">Internally, Objective-J compiles class references to a lookup in <span style="color:rgb(0,0,0);font-family:Menlo,monospace;font-size:11px;line-height:13px;white-space:pre">REGISTERED_CLASSES</span><span style="color:rgb(0,0,0);line-height:13px;white-space:pre"><font face="arial, helvetica, sans-serif">, which serves a similar purpose, but allows for nicer syntax through a preprocessor.</font></span></div>

<div class="gmail_extra"><br></div><div class="gmail_extra">This use-case would not be addressed by improved lexical inference of names in functions and classes, but the final module proposal will hopefully moot this use-case. There are probably other lookup-by-reference use-cases that would not be handled by modules.</div>

<div class="gmail_extra"><br></div><div class="gmail_extra"><b>Debugging</b><br></div><div class="gmail_extra"><b><br></b></div><div class="gmail_extra">Similarly, Ember provides a default <font face="courier new, monospace">toString</font> that is more descriptive than the default <font face="courier new, monospace">[object Object]</font>.</div>

<div class="gmail_extra"><br></div><div class="gmail_extra"><font face="courier new, monospace">App = Ember.Namespace.create();</font></div><div class="gmail_extra"><font face="courier new, monospace">App.Person = Ember.Object.extend();</font></div>

<div class="gmail_extra"><font face="courier new, monospace">App.Person.toString(); // "App.Person"</font></div><div class="gmail_extra"><font face="courier new, monospace">var person = new App.Person();</font></div>

<div class="gmail_extra"><font face="courier new, monospace">person.toString() // "<App.Person:ember1234>"</font></div><div class="gmail_extra"><font face="courier new, monospace"><br></font></div><div class="gmail_extra">

<font face="arial, helvetica, sans-serif">The part after the colon is a debug-friendly object ID we lazily create when needed. (also, until we have a reliable Set, Map and WeakMap, that object ID is also used as the key in Objects that are used to emulate Sets, Maps and WeakMaps).</font></div>

<div class="gmail_extra"><br></div><div class="gmail_extra">Historically, we have tried to install these <font face="courier new, monospace">toString</font> values as <font face="courier new, monospace">displayName</font><font face="arial, helvetica, sans-serif">. Because Chrome does not support </font><span style="font-family:'courier new',monospace">displayName</span><font face="arial, helvetica, sans-serif">, we eventually stopped trying to add it. (also, our current lookup implement is lazy, like </font><span style="font-family:'courier new',monospace">toString</span><font face="arial, helvetica, sans-serif">, and </font><span style="font-family:'courier new',monospace">displayName</span><span style="font-family:arial,helvetica,sans-serif"> </span><span style="font-family:arial,helvetica,sans-serif">is an eager value).</span></div>

<div class="gmail_extra"><span style="font-family:arial,helvetica,sans-serif"><br></span></div><div class="gmail_extra"><span style="font-family:arial,helvetica,sans-serif">For what it's worth, Chrome's attempt to guess names in lieu of support for </span><span style="font-family:'courier new',monospace">displayName</span><span style="font-family:arial,helvetica,sans-serif">, while better than nothing, isn't good enough in many cases and blocks us from providing the best possible debugging experience in the Chrome debugger. Many others have been similarly stymied, the Chrome ticket to support </span><font face="courier new, monospace">displayName</font><span style="font-family:arial,helvetica,sans-serif"> (</span><a href="https://code.google.com/p/chromium/issues/detail?id=17356">https://code.google.com/p/chromium/issues/detail?id=17356</a>) has been open since 2009 and has comments as recently as this year.</div>

<div class="gmail_extra"><br></div><div class="gmail_extra">For this use-case, Maciej or Dave's proposal at <a href="http://wiki.ecmascript.org/doku.php?id=strawman:name_property_of_functions">http://wiki.ecmascript.org/doku.php?id=strawman:name_property_of_functions</a> would be helpful. I like Dave's variant (which allows specification of separate call behavior, construct behavior and an alternative prototype to <font face="courier new, monospace">Function.prototype</font>). This would allow a very simple implementation of imperative class-side inheritance, among other things. I know this can be achieved via proxies and/or <font face="courier new, monospace">__proto__</font>, but this is much nicer.</div>

<div class="gmail_extra"><br></div><div class="gmail_extra">In general, I like the idea of inferring useful information statically. The one caveat is that libraries creating class-like abstractions usually create constructors inside of the implementation. In Ember's case (see <a href="http://jsbin.com/ijicor/78">http://jsbin.com/ijicor/78</a>), this means that the statically inferred name is always <font face="courier new, monospace">Class</font>. Interestingly (and usefully), Firefox uses the provided <font face="courier new, monospace">toString</font> value in its output.</div>

<div class="gmail_extra"><br></div><div class="gmail_extra">In a similar Backbone example (see <a href="http://jsbin.com/uqanem/1">http://jsbin.com/uqanem/1</a>), Chrome infers <font face="courier new, monospace">d</font>, and prints <span style="font-family:'courier new',monospace">d</span> plus a set of internal attributes. Firefox just prints the internal attributes.</div>

<div class="gmail_extra"><br></div><div class="gmail_extra">Of course, in the long run, many of these non-transpiled use cases would be handled by a robust and broadly implemented declarative class syntax. Transpiled use cases (like the original case, Objective-J) would probably continue to benefit from more control over the name.</div>

<div class="gmail_extra"><br></div><div class="gmail_extra"><b>TL;DR</b></div><div class="gmail_extra"><b><br></b></div><div class="gmail_extra">I would really like to see Dave's <font face="courier new, monospace">Function.create(name, call, construct, proto)</font> proposal come to pass. Fleshing out static name extraction as described above would be a big benefit to a lot of common uses, and I am in favor of it. Direct control of the name, not static inference, is needed for imperative class-like abstractions.</div>

<div class="gmail_extra"><br><div class="gmail_quote">On Sat, Nov 17, 2012 at 7:44 PM, Brandon Benvie <span dir="ltr"><<a href="mailto:brandon@brandonbenvie.com" target="_blank">brandon@brandonbenvie.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Excellent! I must admit to having a pretty ridiculous obsession with the name property of functions in particular, so I would be much delighted to see improvements and standardization come to it.<div class="">

<div class="h5"><div class="gmail_extra"><br>
<br><div class="gmail_quote">On Sat, Nov 17, 2012 at 9:06 PM, Brendan Eich <span dir="ltr"><<a href="mailto:brendan@mozilla.org" target="_blank">brendan@mozilla.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


Brandon: thanks for reviving and revising my old strawman. I will edit your proposed changes in (and let you and the list know when I'm done so you can review) and present at the TC39 meeting in the last week of November. Thanks again, great work!<br>



<br>
/be<br>
<br>
Brandon Benvie wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div>
Declarative scope...not decorative scope. Curses auto correct fail.<br></div><div>
______________________________<u></u>_________________<br>
es-discuss mailing list<br>
<a href="mailto:es-discuss@mozilla.org" target="_blank">es-discuss@mozilla.org</a><br>
<a href="https://mail.mozilla.org/listinfo/es-discuss" target="_blank">https://mail.mozilla.org/<u></u>listinfo/es-discuss</a><br>
</div></blockquote>
</blockquote></div><br></div>
</div></div><br>_______________________________________________<br>
es-discuss mailing list<br>
<a href="mailto:es-discuss@mozilla.org">es-discuss@mozilla.org</a><br>
<a href="https://mail.mozilla.org/listinfo/es-discuss" target="_blank">https://mail.mozilla.org/listinfo/es-discuss</a><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br>Yehuda Katz<br>(ph) 718.877.1325<br>
</div>