Andreas Rossberg <mailto:[email protected]>
January 24, 2012 12:22 PM

Actually, it is possible if this is a check for a primordial,

This isn't about built-ins. But also I don't believe we should move the core built-ins to a prototype of the global object. That's an observable change since ES3. Maybe not breaking, who knows?

and you
move them to the prototype of global this and allow shadowing them.
Then you'd be able to write:

let foo = Object.getPrototypeOf(this).foo || function() { ... }

(I think we had something like this on the board once.) Or, in the
browser, if window was actually bound to that prototype,

window === this -- it must be the WindowProxy for the Window object that is the global scope.

this simplifies to:

let foo = window.foo || function() { ... }

This will not work if the detection is coping with prior scripts that bound let bindings, since we agreed that you cannot redeclare a given identifier using let.

If each script's lexical scope is isolated, then of course there's no problem in "redeclaring", but detection breaks. Detection is based on objects, not bindings, in this kind of code (there are other detection patterns).

I don't think compatibility can afford binding window to something
different than global this, though.

Whew! I was wondering.

(One could still pre-bind the prototype to a different name, however.)

(Do not want.)

Of course, I sincerely hope that the module system will provide a more
pleasant replacement for this pattern. :)

But what? If it's let-based I'd like to know how it could work.

/be

Brendan Eich <mailto:[email protected]>
January 24, 2012 11:24 AM
Andreas Rossberg <mailto:[email protected]>
January 24, 2012 10:32 AM

Taken literally, an implicit block scope at toplevel would imply that
let/const-bound properties won't show up on the global object at all.
That seems to devalue the global object and/or let.

I prefer to think of it as saving 'let' from the degradations of the global object ;-).

I am skeptical we will banish var, ever. Consider the object detection pattern:

  if (!this.foo) {
    var foo = function () {
      ...
    };
  }

No way to make this work with let.

(Part of) what I proposed in the OP of this thread is that for the
toplevel, we can still safely reflect let/const bindings on the global
object, but through accessor properties -- just like with module
instance objects. Solves all the problems we just discussed, while
also keeping let useful as the new var.

I saw, clever approach -- haven't had time to evaluate it for compatibility. Seems optimizable.

/be

Andreas Rossberg <mailto:[email protected]>
January 24, 2012 10:32 AM

Taken literally, an implicit block scope at toplevel would imply that
let/const-bound properties won't show up on the global object at all.
That seems to devalue the global object and/or let.

(Part of) what I proposed in the OP of this thread is that for the
toplevel, we can still safely reflect let/const bindings on the global
object, but through accessor properties -- just like with module
instance objects. Solves all the problems we just discussed, while
also keeping let useful as the new var.

Var would keep its current semantics, aliasing a data property. For
functions, it doesn't matter much either way, but for consistency with
other static bindings I'd move to accessor-based semantics in ES6.

/Andreas

Brendan Eich <mailto:[email protected]>
January 24, 2012 9:49 AM
Andreas Rossberg <mailto:[email protected]>
January 24, 2012 2:37 AM
On 23 January 2012 19:25, Brendan Eich<[email protected]>  wrote:
Andreas Rossberg<mailto:[email protected]>:
V8 currently allows

   var w = 1; w = 2; print(w); const w = 3

which will output 2. The idea most likely was that const should behave
like var. This, and other, similar examples clearly have to break if
should const become official in classic mode, so the compatibility
argument may not carry far.
SpiderMonkey:

js>  var w = 1; w = 2; print(w); const w = 3
typein:19: TypeError: redeclaration of var w:
typein:19: var w = 1; w = 2; print(w); const w = 3
typein:19: ....................................^

js>  var w = 1
js>  const w = 3
typein:22: TypeError: redeclaration of var w

However:

js>  const w = 3; var w = 1; print(w);
3

This follows from var not disturbing a pre-existing binding. Or so we thought long ago when adding const, but that was years before const as initialize-only-and-at-most-once let.
Why does V8 do something else, do you know the impetus for diverging?

No, unfortunately I don't know the full history there. I can try to find it out.

But just to be obnoxious, with Firefox:

print(c);
Object.defineProperty(this, 'c', {value: 1});
print(c);
const c = 2;
print(c);
=>  undefined 1 2

You bet -- const does redefine the global property, unlike var. This is not something we propose for standardization, of course!
Or even:

print(c);
Object.defineProperty(this, 'c', {value: 1, writable: true});
print(c);
c = 2;
print(c);
const c = 3;
print(c);
=>  undefined 1 2 3

Apparently, FF avoids breaking the object model only for the price of
keeping the non-writable const property configurable until the actual
initialization -- effectively breaking const completely.

More fun:

js> function f(k) {
  for (var i = 0; i < k; i++) {
    const j = i*i;
    a.push(j);
  }
}
js> a = []
[]
js> f(10)
js> a
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

SpiderMonkey const has never been initialize-at-most-once. Some people claim to like this, but we are going to try breaking it in favor of ES6.

Consequently, I maintain my claim that it is impossible to reconcile
sane let/const semantics with the idea of having toplevel bindings
represented as data properties on the global object.

I agree. For ES4 we equated let to var at top-level, a mistake. For ES6 IIRC you have proposed an implicit block scope at top level (of functions at least, I don't see why not programs as well), whereby let and const bind lexically. Only var and function make global object properties.

  If there is some
trick for "hiding" accessor semantics that doesn't break the object
model then I'd be really interested in seeing it. :)

Me too.

/be

Andreas Rossberg <mailto:[email protected]>
January 24, 2012 2:37 AM
On 23 January 2012 19:25, Brendan Eich<[email protected]>  wrote:
Andreas Rossberg<mailto:[email protected]>:
V8 currently allows

   var w = 1; w = 2; print(w); const w = 3

which will output 2. The idea most likely was that const should behave
like var. This, and other, similar examples clearly have to break if
should const become official in classic mode, so the compatibility
argument may not carry far.
SpiderMonkey:

js>  var w = 1; w = 2; print(w); const w = 3
typein:19: TypeError: redeclaration of var w:
typein:19: var w = 1; w = 2; print(w); const w = 3
typein:19: ....................................^

js>  var w = 1
js>  const w = 3
typein:22: TypeError: redeclaration of var w

However:

js>  const w = 3; var w = 1; print(w);
3

Why does V8 do something else, do you know the impetus for diverging?

No, unfortunately I don't know the full history there. I can try to find it out.

But just to be obnoxious, with Firefox:

print(c);
Object.defineProperty(this, 'c', {value: 1});
print(c);
const c = 2;
print(c);
=>  undefined 1 2

Or even:

print(c);
Object.defineProperty(this, 'c', {value: 1, writable: true});
print(c);
c = 2;
print(c);
const c = 3;
print(c);
=>  undefined 1 2 3

Apparently, FF avoids breaking the object model only for the price of
keeping the non-writable const property configurable until the actual
initialization -- effectively breaking const completely.

If the property wasn't configurable, then the initialization would
need to modify a non-writable, non-configurable data property, which
is a clear violation of the JS object model. It is what V8 does,
though. So in V8, the above examples are rejected, but instead,
objects break.

Consequently, I maintain my claim that it is impossible to reconcile
sane let/const semantics with the idea of having toplevel bindings
represented as data properties on the global object. If there is some
trick for "hiding" accessor semantics that doesn't break the object
model then I'd be really interested in seeing it. :)

/Andreas

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

Reply via email to