[+stay] Another bit of evidence for lexical this, and thus for block lambdas over arrow functions or simple # functions.
At < http://wiki.ecmascript.org/doku.php?id=harmony:proxies&rev=1308499413&do=diff> I corrected a bug noticed just now by Mike Stay (cc'ed). The bug dates from < http://wiki.ecmascript.org/doku.php?id=harmony:proxies&rev=1280925681#trap_defaults> in August of 2010, more than 10 months ago, when Tom van Cutsem wrote: keys: function() { return this.getOwnPropertyNames().filter( function (name) { return this.getOwnPropertyDescriptor(name).enumerable }); } This bug was written by one of the most talented and careful programmers I have ever met. The page it appears in has been carefully examined by many experts (not just official experts -- real experts) and a large community of talented people, guiding at least three implementations of the proxy system. The bug was only noticed by Mike Stay while starting the newest of these implementation efforts, emulating proxies on old browsers within ES5/3. Most JavaScript code will be much less reviewed than this, and by a community less expert than ourselves in the peculiarities of the language. We need to ask, why was this bug so easy for an expert to make and so hard for a community of experts to catch? My guess is that it's because Array.prototype.filter "feels" like a control structure and the anon function we're calling it with "feels" like a control structure block, even though we know that we know otherwise. When we see the "this" inside and try to figure out what it means, we search outward for a "function" and our eye often catches the wrong one. Let's see what Tom might have written with three of the other function-like proposals. To be fair, I'll assume here that "return" can be omitted in all. Arrow functions: keys: function() { return this.getOwnPropertyNames().filter( (name) -> this.getOwnPropertyDescriptor(name).enumerable ); } Simple # functions keys: function() { return this.getOwnPropertyNames().filter( #(name) { this.getOwnPropertyDescriptor(name).enumerable }); } block lambdas keys: function() { return this.getOwnPropertyNames().filter { |name| this.getOwnPropertyDescriptor(name).enumerable } } The first and obvious point I'm making is that Tom would not have made this particular mistake with block lambdas, but I recognize that this argument cuts both ways. Other uses may have the opposite hazard, and we need to examine this as well. The new point is that arrow functions and simple # functions make the original hazard *worse*, because, like "function", they still rebind this. But by being less verbose than "function", it's even easier for the eye to miss them when seeing a "this" in their body and trying to determine what it means. The more I think about this, the more I'm inclined to believe that, for functions which rebind "this", the verbosity of "function" is a virtue. As fallible programmers, we can only afford a more compact function notation for defining functions with lexical "this" -- like block lambdas. -- Cheers, --MarkM
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

