On Oct 8, 2012, at 8:29 AM, Andreas Rossberg wrote:
> On 6 October 2012 02:35, Allen Wirfs-Brock <[email protected]> wrote:
>> Bottom line,
>> I suggest we implement proposal 3, rather than the temporary conclusions
>> that were discussed at the Sept. meeting.
>
> Of the options you suggest, I also think that #3 is preferable.
>
> However, your examples have reconfirmed my suspicion that having
> defaults live within the scope of local declarations is the path to
> insanity. I suggest that we reconsider. There should be a clean,
> simple, and sane nesting of scopes here.
You desugaring would break ES<=5.1 compatibility for:
(unction (p) {
var p;
return typeof p
})("test")
ES5.1 returns "string", your desugaring returns "undefined"
I'm actually favorably included towards the intent of your proposal: parameter
default value expressions can't reference bindings introduced in the body.
However, it needs to be specified in a way that preserves ES5.1 semantics. I
also think that, for new parameter constructs, that names defined in the
parameter list should not be allowed to be the same as a function top-level
declaration. EG,
We have to allow this:
function f(p) {
var p;
}
but we don't have to allow:
function f( ...p) {
var p;
};
So, my alternative proposal #4 is:
a) ES<=5.1 style formal parameters lists introduce var bindings and
follow ES5.1 initialization rules. This permits top level inner functinon and
var declarations that use the same name as a parameter.
b) parameter lists containing any new ES6 syntax introduce let bindings
for the parameters. This prohibits multiple declaration of a formal parameter
name and inner var/function redeclaration of a parameter name.
c) parameter default value expressions do not have visibility of
bindings created within the function body.
Allen
>
> Let me try again. How about the following desugaring?
>
> function f(x1 = e1, ~~~, xN = eN) { body }
>
> means
>
> function f(x1, ~~~, xN) {
> if (x1 === undefined) x1 = e1;
> ~~~
> if (xN === undefined) xN = eN;
> return (function(x1, ~~~, xN) { body })(x1, ~~~, xN);
> }
>
> That is:
>
> * no local declaration is visible in any of the defaults
> * defaults can see other parameters, but they are initialized left to right
> * local declarations behave as always, no extra rules needed
>
> There is an additional advantage to this scheme: to understand the
> definition of a default a caller never needs to look at the
> implementation details of f's body -- which I think is a very useful
> property. In particular, if a default expression is itself a function,
> and closes over one of the other arguments, then you actually get what
> you'd expect even if f, way down in its body, messes with some of
> those arguments (e.g. abusing them as a loop variable):
>
> function f(i, log = (s) => print("f(" + i + "): " + msg)) {
> log("starting...");
> while (i > 0) {
> log("processing " + i);
> // ... whatever
> --i;
> }
> log("done...");
> }
>
> f(6); // no surprises here
>
> /Andreas
>
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss