issue: function hoisting and parameter default value initialization

Andreas Rossberg rossberg at google.com
Mon Oct 8 08:29:27 PDT 2012


On 6 October 2012 02:35, Allen Wirfs-Brock <allen at wirfs-brock.com> 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.

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


More information about the es-discuss mailing list