Allen Wirfs-Brock wrote:
On Sep 8, 2012, at 3:51 PM, Brendan Eich wrote:
Allen Wirfs-Brock wrote:
On Sep 8, 2012, at 3:20 PM, Brendan Eich wrote:

SpiderMonkey (Firefox 15 and newer has default parameters):

js>   function f(a = g) { function g(){}; return a; }
js>   f()
function g(){}

So function g is hoisted and a defaults to it, as expected.
While I agree that the above is reasonable behavior.  It wasn't the consensus 
that was reach earlier this year at the Jan.  (or may March??) meeting.  What 
we agreed upon is that default value expressions in parameter lists have 
visibility to the left and upward in scope but do not have visibility of 
anything declared within the curlies that surround the body.   So, in the above 
example, g should be a reference error when evaluated as a default value 
initializer.

As the NOTE in step 9 of 10-5-3 says:

        NOTE    Binding Initialisation for formals is performed prior to 
instantiating any non-parameter declarations in order to ensure that any such 
local declarations are not visible to any parameter Initialisation code that 
may be evaluated.
You're right, I had forgotten that.

Is it well-motivated other than in the naive left-to-right sense, which 
function hoisting already violates? Perhaps, because parameters to the right 
are not yet bound.

Personally, I think the consensus rules create special case anomaly  in the 
scoping rules that it would be good to avoid.  However, some of the TC39 member 
had a hard time accepting that the parameter list had visibility into what they 
perceived as a deeper level of curlies (the function body).  Personally, I 
would prefer to just think of the parameter list declaration as being logically 
part of the function body and treat all declaration in that scope contour 
consistently.

I agree. ES1-5 had no observable scope or hoisting boundaries among parameters, or between parameters and body top-level bindings.

I say we re-raise this at the TC39 meeting week after next. What say you?

If so, then I can live with it, and g in the f(a = g) bit above would use an 
outer g, if any (or throw on undefined g).

But this still does not mean the implicit |yield;| at entry to generator function should 
be other than observably "after" parameter defaulting, so that we get the throw 
at loc 1. Right?

Right. It just means have to place the initial implicit (almost) yield right at 
the end of generator declaration

s/generator/parameter/

instantiation and before any user code executes.

(I have more to say about that in a separate message)

IOW, this is a tangent, good to nail down (sorry for prying it up), but not a 
crucial experiment for generator default parameter semantics.

Right, it's a separate issue and it's good that you identified that the FF 
implementation doesn't match the spec.

Indeed the prototype default parameter implementation in Firefox (SpiderMonkey) has more of what you and I prefer:

js> function f(a, b=a, c=d, d=d) {return [a,b,c,d]}
js> var d='global'
js> f(1)
[1, 1, (void 0), (void 0)]
js> f(1,2)
[1, 2, (void 0), (void 0)]
js> f(1,2,3)
[1, 2, 3, (void 0)]
js> f(1,2,3,4)
[1, 2, 3, 4]

Note no outer 'd' shows up in the result of f(1,2). When SpiderMonkey implements support for undefined as the default-triggering sentinel, then we'd have

js> f(1, 2, void 3)
[1, 2, (void 0), (void 0)]
js> f(1, 2, void 3, 4)
[1, 2, 4, 4]

which I prefer on the simpler-to-have-one-contour basis. What do you think?

The TC39 meeting that favored let* (Scheme let*, I mean) binding of parameters seems unnecessarily complicated, without a motivating use-case, and alient to the rest of the language.

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

Reply via email to