Javascript closures bind their free variables by reference;
  what does that mean for const functions?
..
  var real_f;
  const f() { return real_f(); }

I Claus, I'm not sure why this isn't obvious in the current spec. Please
let me know what needs to be modified so that it becomes obvious.

Hi Mark,

this particular issue is more about reader expectations - I probably
browsed that page several times without stumbling over the issue.

Then I was reading Strachey again, as background for the Javascript
References discussion, and I was wondering about toString breaking
static scoping. Only then I noticed that the const functions strawman
leaves open quite a few relevant issues wrt free variables.

If you don't want to change the strawman, I would suggest simply
to add a bit of context information (about "closures take free variables
by reference" and its consequences; some of the examples I gave,
such as fully variable const functions; perhaps the CPL reference),
plus your "modest goal" summary below (const functions aren't
constant, they just have a "shallow-constant" Function object but
deeper modifications are still possible).

That way readers know that there are wider issues, and know that
those issues are not addressed, on purpose (but might be worth
addressing in other proposals).

Otherwise, readers are left to wonder whether the issues of free
variables taken by reference were perhaps missed, or whether
the proposal might be tackling those issues in ways that might
not be obvious to the reader.

That spec has much more modest goals for "const" and defines "const functions" purely in terms of a simple syntactic expansion. Const functions capture variables in exactly the same manner as normal functions, since the variable capture is not altered by the syntactic expansion. This is on purpose -- it is not the intention to alter the variable capture semantics. The function is "const" only in that it does not provide mutability beyond what it explicitly states. All the implicit mutability provided by normal functions -- properties of the function, properties of the function's .prototype, and assignability of the function variable itself, are suppressed. Your example

 var real_f;
 const f() { return real_f(); }

simply expands to

 const f = Object.freeze(function() { return real_f(); });
 Object.freeze(f.prototype);
 var real_f;

While I'm in the area, and since you asked about clarity:-)

I do have some trouble interpreting the Joining section: since it is
extensive, I assume it is important, but what exactly goes wrong if
one does that with functions, and how exactly do const functions
avoid what goes wrong with non-const functions? Does it matter
for Joining that const functions are still mutable?

More importantly, the syntactic transformations of variable declarations are starting to get complex (var,let,const; all const have to come first). I am probably not the first to wonder whether that approach is sufficiently unambiguous to pin down the semantics. For instance,

   {
       const x = 1;
       const y = x;
       const f() { return [x,y,f]; };
       const r = [r];
       const m = doSomethingWith(f);
       const z = f();
   }

Since const functions are just const declarations, the only thing
special about them is that their bodies don't get evaluated until
the function gets called. So how are these declarations going to
get sorted, evaluated, frozen, all the while preventing uninitialized
binding states and not-yet-frozen functions from being observable?

For let/var, the answer is that all the bindings are created
"in parallel", at the cost of all being undefined in the initializers.
But const wants to avoid that gap, and const functions desugar
to declaration plus method calls.

Feel free to drop bindings that are disallowed by some rule I
missed, shrinking to valid parts as necessary. If I follow the rule
from the strawman, I move a const binding for f to the top, or
perhaps below the one for y, together with a couple of calls to
freeze, for function and prototype. Since the freezes are just
function calls, other bindings should be hoisted in front of them?

Apologies if I am again missing the obvious, but it isn't
clear to me how const and const functions work (probably just details).

Since they are not constant, their main gain seems to be that
they cannot have user-defined prototype chains or non-standard
object properties. Am I reading that correctly?

Claus



_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to