arrow syntax unnecessary and the idea that "function" is too long

Dmitry A. Soshnikov dmitry.soshnikov at
Sun May 15 11:55:11 PDT 2011

On 15.05.2011 21:09, Brendan Eich wrote:
> On May 15, 2011, at 8:14 AM, Dmitry A. Soshnikov wrote:
>> // Use # to freeze and join to nearest relevant closure
>> function return_pure() {
>> return #(a)
>>   ->  a * a;
>> }
>> let p = return_pure
>> ()
>> ,
>>      q = return_pure
>> ()
>> ;
>> assert
>> (p === q);
>> So, ES3 joined-objects are back. Though, the question is in their [[Scope]] difference (i.e. can be they joined in the following case):
> The "join to nearest relevant closure" words were meant to address this. Let's see (I made a few typo and syntax fixes):
>> let foo = (...args) ->  {
>>    return #(a) ->;
>> };
>> foo(1, 2, 3)((x) ->  x * x); // [1, 4, 9]
>> foo(5, 10)((x) ->  x * x); // [25, 100]
>> Do both have the same (reflected) [[Scope]] to be joined?
> The two foo calls have different unjoinable scope chains enclosing variables captured by the returned #(a) -> function, specifically args. So that hash-frozen arrow-function cannot be joined into one identity.
>> At first glance with named args, e.g. foo(a, b, c) yes, but what's with rest args?
> Named vs. rest doesn't matter, the question is lexical capture. The name |args| is from the outer
> (...args) ->  { return #(a) ->; }
> function. It is used in the inner arrow function.
> The location of this |args| parameter is what is actually captured in general.

Oh, my misunderstanding then. Then I just incorrectly treated yours

assert(p === q);

I though here you try to show that the engine will handle the case with 
optimization and reuse (i.e. to join) the function object. However, it 
still not possible because of different scope chain, that exactly why I 
was asking.

So you mean just lexical addressing of free variable? I.e. without 
dynamic scope chain lookup (that what Dave Herman confused recently with 
dynamic scope concept IIRC). However it's interesting -- if ES6 will 
have lexical addressing anyway (that is there will be no dynamic 
bindings -- no `eval`, no `with`, etc, -- just compile-time bindings), 
this means that this optimization will be done in any way, -- without 
needing of this #function in this case. Or am I mistaken again?

Thanks for explanations btw.


>   This is optimizable to copying the value at that location in many cases, including this one, but that doesn't change the fact that the location varies with each call to foo.
> So args' abstract location differs, and therefore its value may differ, each time the inner arrow-function is evaluated. So the # freezes it but it will not be joined with other evaluations of the same source form.
> However you implement closures, something has to vary each time the inner arrow is evaluated, to capture the correct args, [1, 2, 3] or [5, 10].

More information about the es-discuss mailing list