A shorthand for Object.defineProperty?

Brendan Eich brendan at mozilla.com
Tue Jun 21 11:21:10 PDT 2011


On Jun 21, 2011, at 2:18 AM, Axel Rauschmayer wrote:

>>>>> Do we really need the dynamic this arrow ->, or can we make do with just the lexical this arrow =>.
>>> Are functions that depend on dynamic |this| ever *not* methods?
>> 
>> Sure. The main use-case is constructors (and you can make a function do double-duty, as a constructor or a function called without 'new').
> 
> With classes, constructors will become methods, right?

Not in the sense we were discussing, where you could call new o.C or else o.C().

Yes, C.prototype.constructor === C, but people don't write "x = new C; y = new x.constructor" much. You can, that is possible in JS today without classes.

Again, classes are sugar for the prototypal pattern. They don't add anything different or magic about how the constructor and the prototype reference each other.


>> Also, some times, people write functions not used as methods but called via .call or .apply. It happens.
> 
> Wouldn’t it be better to have lexical |this| in these cases, so that foo.call(null, ...) does not affect |this|?

No, the .call and .apply cases I cited, which intentionally pass varying (dynamic) objects as the first argument, need that first argument to bind to the |this| parameter.


>>> Wouldn’t you always want to use an object literal for methods, especially if some features (such as |super|) depend on it?
>> 
>> Probably. But so what?
>> 
>> We're not making mandatory syntax either way with function, so why should we with arrow?
> 
> Old-style functions would be rarely used and there would be a clear separation of concerns:
> - Want a method? Use an object literal.

That's too restrictive. JS allows the Google Closure style of assigning methods via C.prototype.m1 = function.., etc.


> - Want a function that is not a method (i.e., lexical this)? Use an arrow function with =>

I think you are trying to restrict JS users in ways they won't like. Anyway, we can't make an incompatible change to functions. Arrows as proposed are just syntax for functions, including with |this| bound lexically.

If we make arrows restrictive in ways that functions (with either dynamic or lexical this-binding) are not restricted, we're essentially telling some JS programmers that they're "doing something wrong" or "using forms that are hard to understand for beginners".

Sorry, there's no evidence for such claims, and without such evidence, it's not a good idea for TC39 to put itself in such a "restrictionist" position.

(Contrast this with 'with', dynamic eval var injection, and other things banned by strict mode where lexical scope, capability leaks, and optimizability were all destroyed by the banned forms.)


> This would make things easier to understand. When I explain this aspect of JavaScript to others, they are often stumped, but I have never encountered anyone who was confused by Python:
> class MyClass:
>     def mymethod(self):
>         return "hello world"
> def myfunction():
>     return "hello world"
> 
> So this is probably my real point: can we make things as un-confusing as in Python?

Python has its confusing parts too.

Anyway, if you are talking about making classes less confusing, that's a fine goal for classes.

But shorter function syntax needs to be shorter without requiring only "lexical this", given all the "dynamic this" use-cases including methods assigned as in Google Closure. Functions are used in several ways in JS and the overlong syntax (both 'function' and 'return') are a problem for several of the use-cases.

Method syntax as specified for Harmony inside object literals *does* have dynamc this-binding. There's no dispute about that.


>>> Maybe I just like the distinction introduced by block lambdas too much:
>>> - dynamic this --> existing functions and methods
>>> - lexical this --> new, more compact construct, mainly used as the argument of functions and methods.
>> 
>> Block-lambdas are not arrows. Arrows are just syntax and try to shorten function usage in general (including the .bind or var self=this; idiom). Block-lambdas must preserve Tennent's Correspondence Principle, so they have no choice but to treat |this| lexically.
> 
> I know. But block-lambdas enforce a separation of concerns (because they have no choice, really) that I would like short-syntax functions (arrows or not) to enforce, as well.

That's nice for the use-cases that want lexical-this. For dynamic-this, it's a usability burden without justification.

Explaining things to beginners still will involve explaining 'function' (long-form) syntax for the foreseeable future, so you don't gain anything by crippling arrow syntax.

But once beginners learn more, they will hate having to write out the long form for all the dynamic this cases that can't be written using method-in-initialiser syntax.


>>> This distinction works well as a rule of thumb and keeps things easy to explain.
>> 
>> It's not that simple: existing functions can and do use various binding hacks to make |this| or a substitute "lexical". Anyway, functions have |this| parameters, whether created by old function or new arrow syntax.
> 
> Right. That could be a problem, the abstraction I have in mind might become leaky at some point.

We want orthogonal primitives with good syntax. This not only reduces such "leaks" but increases serendipity. Users will discover things we did not foresee, which otherwise would be restricted in lumpy or hard-to-use ways, or just impossible.

/be

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110621/660aef68/attachment.html>


More information about the es-discuss mailing list