Oh, and just a small note -- perhaps there's a sense to put a comment near each line to what result the expression evaluates in your examples, e.g.

asset(p === q); // true (or false?)

etc.

Dmitry.

On 15.05.2011 22:55, Dmitry A. Soshnikov wrote:
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) ->  args.map(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) -> args.map(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) ->  args.map(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.

Dmitry.

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].



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

Reply via email to