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

_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to