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