Re: Default @@toStringTag for user classes
It probably would be backward incompatible change. Too much code depends on [Object Object]. 2 gru 2014 08:46 Dmitry Soshnikov dmitry.soshni...@gmail.com napisał(a): Hi, Probably worth providing a default implementation of the `@@toStringTag` when evaluating a class [1]. In this case users will be able to do: ``` class Point { ... } var p = new Point(1, 2); console.log(p); // [object Point] ``` The default implementation will be just (if the `className` is defined of course): ``` proto[@@toStringTag] = function() { return className; }; ``` [1] https://people.mozilla.org/~jorendorff/es6-draft.html#sec-runtime-semantics-classdefinitionevaluation Dmitry ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Default @@toStringTag for user classes
Le 2 déc. 2014 à 09:04, Michał Wadas michalwa...@gmail.com a écrit : It probably would be backward incompatible change. Too much code depends on [Object Object]. I'm curious to know what sort of code would be broken by `O.p.toString.call(x) === [object Point]` for instances `x` of some user-defined class? and whether it is not already broken by, say, `O.p.toString.call(new Set) === [object Set]`? —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Default @@toStringTag for user classes
Same question here. AFAIK usually the `({}.toString.call(generic) === [object Object])` check is the `default:` in a switch, the last `else` in a flow, etc etc ... although I wouldn't be surprised if some code, somewhere, would do strict comparison to know if it's a user defined object or not. In that case there will be problems. To be honest I also don't see much advantage in having this configurable when `obj.constructor.displayName` or `obj.constructor.name` can be checked instead and eventually fallback into `Object.prototype.toString.call(obj)` This will work backward compatible too br On Tue, Dec 2, 2014 at 12:03 PM, Claude Pache claude.pa...@gmail.com wrote: Le 2 déc. 2014 à 09:04, Michał Wadas michalwa...@gmail.com a écrit : It probably would be backward incompatible change. Too much code depends on [Object Object]. I'm curious to know what sort of code would be broken by `O.p.toString.call(x) === [object Point]` for instances `x` of some user-defined class? and whether it is not already broken by, say, `O.p.toString.call(new Set) === [object Set]`? —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties
On 1 December 2014 at 03:12, Mark S. Miller erig...@google.com wrote: On Sun, Nov 30, 2014 at 12:21 PM, Boris Zbarsky bzbar...@mit.edu wrote: Per spec ES6, it seems to me like attempting to define a non-configurable property on a WindowProxy should throw and getting a property descriptor for a non-configurable property that got defined on the Window (e.g. via var) should report it as configurable. Can you clarify? Do you mean that it should report properties as configurable, but still reject attempts to actually reconfigure them? Also, how would you allow 'var' to even define non-configurable properties? If you want DefineProperty to throw on any such attempt, then 'var' semantics would somehow have to bypass the MOP. From prior similar experiences, the way to get this fixed quickly is to add test262 tests which fail on these violations. All browsers have been much quicker to fix breakage that shows up in test262 results than to mere bug reports. Well, let's find a workable semantics first. :) /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties
Hi, I feel like I've been in an equivalent discussion some time ago, so taking the liberty to answer. Le 02/12/2014 13:59, Andreas Rossberg a écrit : On 1 December 2014 at 03:12, Mark S. Miller erig...@google.com wrote: On Sun, Nov 30, 2014 at 12:21 PM, Boris Zbarsky bzbar...@mit.edu wrote: Per spec ES6, it seems to me like attempting to define a non-configurable property on a WindowProxy should throw and getting a property descriptor for a non-configurable property that got defined on the Window (e.g. via var) should report it as configurable. Can you clarify? Do you mean that it should report properties as configurable, but still reject attempts to actually reconfigure them? Yes. This is doable with proxies (which the WindowProxy object needs to be anyway). * the defineProperty trap throws when it sees configurable:false * the getOwnPropertyDescriptor trap always reports configurable:true * and the target has all properties actually configurable (but it's almost irrelevant to the discussion) Also, how would you allow 'var' to even define non-configurable properties? If you want DefineProperty to throw on any such attempt, then 'var' semantics would somehow have to bypass the MOP. Thinking in terms of proxies, the runtime can have access to the target and the handler while userland scripts only have access to the proxy (which the HTML Living standard mandates anyway with the difference between Window and WindowProxy objects. No userland script ever have access to the Window object). The handler can have access to the list all declared variable to know which property should behave as if non-configurable. David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties
Le 02/12/2014 14:24, David Bruant a écrit : Hi, I feel like I've been in an equivalent discussion some time ago The topic felt familiar :-p http://lists.w3.org/Archives/Public/public-script-coord/2012OctDec/0322.html David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties
Yes. I was glad to find in that message a pointer back to https://mail.mozilla.org/pipermail/es-discuss/2012-December/027114.html On Tue, Dec 2, 2014 at 5:36 AM, David Bruant bruan...@gmail.com wrote: Le 02/12/2014 14:24, David Bruant a écrit : Hi, I feel like I've been in an equivalent discussion some time ago The topic felt familiar :-p http://lists.w3.org/Archives/Public/public-script-coord/2012OctDec/0322.html David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Text by me above is hereby placed in the public domain Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties
On 12/2/14, 4:59 AM, Andreas Rossberg wrote: On 1 December 2014 at 03:12, Mark S. Miller erig...@google.com wrote: On Sun, Nov 30, 2014 at 12:21 PM, Boris Zbarsky bzbar...@mit.edu wrote: Per spec ES6, it seems to me like attempting to define a non-configurable property on a WindowProxy should throw and getting a property descriptor for a non-configurable property that got defined on the Window (e.g. via var) should report it as configurable. Can you clarify? Do you mean that it should report properties as configurable, but still reject attempts to actually reconfigure them? Yes, correct. Also, how would you allow 'var' to even define non-configurable properties? Because var operates on the global directly. The global is a Window, not a WindowProxy and has no magic behavior. If you want DefineProperty to throw on any such attempt, then 'var' semantics would somehow have to bypass the MOP. The idea is that WindowProxy's [[DefineOwnProperty]] would throw as needed. Window's [[DefineOwnProperty]] is just http://people.mozilla.org/~jorendorff/es6-draft.html#sec-ordinarydefineownproperty -Boris ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties
On 12/2/14, 5:24 AM, David Bruant wrote: The handler can have access to the list all declared variable to know which property should behave as if non-configurable. That's not even needed. If the handler just passes configurable defines on through to the target for a property declared via var, they will end up in http://people.mozilla.org/~jorendorff/es6-draft.html#sec-validateandapplypropertydescriptor and throw in step 5. -Boris ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Default @@toStringTag for user classes
Le 2 déc. 2014 à 08:46, Dmitry Soshnikov dmitry.soshni...@gmail.com a écrit : Hi, Probably worth providing a default implementation of the `@@toStringTag` when evaluating a class [1]. In this case users will be able to do: ``` class Point { ... } var p = new Point(1, 2); console.log(p); // [object Point] ``` You seem to imply that `console.log(p)` will show the result of `p.toString()` in the console. But it is not the case for the majority of browsers. I've just tried: ``` var Point = function() {} Point.prototype.toString = function() { return (this is an object of type Point) } console.log(new Point) ``` Results are: Firefox: Object { } Chrome: Point{toString: function} Safari: Object IE: [object Object](this is an object of type Point) In particular, note that Chrome doesn't need the help of `.toString()` in order to log useful information. —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Removal of WeakMap/WeakSet clear
On 29 November 2014 at 22:30, Mark S. Miller erig...@google.com wrote: On Fri, Nov 28, 2014 at 4:21 AM, Andreas Rossberg rossb...@google.com wrote: [...] With a normal ephemeral weak map implementation, like the one in V8, the value in a (map,key,value) triple can be reclaimed _immediately_ (in the same cycle) when _either_ the map _or_ the key dies. Hi Andreas, it is at this claim that I get confused. This is certainly not true for a normal *ephemeron* map implementation, and is not true for any ephemeron implementation I've read about, including years of prior postings here on es-discuss. If this is true for v8, great! Please walk me through what the v8 implementation does under the following scenario: m = new WeakMap(); non_garbage_var = m; //... stuff not changing whether m is garbage //... scavenge { const k = {}; const v = [k, m]; m.set(k, v); } //...assume that variables k and v are no longer reachable. //...scavenge // m has remained non-garbage the whole time. // Immediately after the scavenge above, have k and/or v been either collected or promoted? In a minor collection nothing is collected, because it doesn't handle ephemerons at all. If a major collection happens after the block, then both k and v (or any such cycle, for that matter) are reclaimed during that collection. (Ignoring complications like incremental marking, which might already have marked k and v live while the block was still active.) In a transposed representation for weak maps with key lists, a minor collection would not collect anything either, because k would still be reachable from m through its list of keys (and minor doesn't handle ephemerons specially). A major collection would be able to remove k from m's key list and reclaim it. I am also interested in the transposed scenario: k = {}; non_garbage_var = k; //... stuff not changing whether k is garbage //... scavenge { const m = new WeakMap(); const v = [k, m]; m.set(k, v); } //...assume that variables m and v are no longer reachable. //...scavenge // k has remained non-garbage the whole time. // Immediately after the scavenge above, have m and/or v been either collected or promoted? In both minor or major collection both m and v are immediately reclaimed, because neither is strongly reachable at that point (unless the WeakMap is pretenured, which would make it survive the minor). However, in a transposed representation for weak maps, a minor collection would no longer reclaim anything, because m would actually be reachable from k (and minor collections do not handle ephemerons specially). A major collection would still reclaim both m and v immediately, _presuming_ m has a list of keys, which it can traverse to find k and remove itself from it. If that wasn't the case, the major collection could _not_ reclaim m or v in this cycle. So having a list of keys in the transposed map representation potentially causes some keys to survive a _minor_ collection, but prevents values from surviving a _major_ collection. Independent of that, the transposed map representation makes scenario 2 worse wrt minor collections. If the existing v8 implementation efficiently collects v as of the second scavenge in both scenarios, or even if there is any known way of doing so efficiently (that also deals with the general ephemeron issue), I would be pleasantly astonished. My assumptions would indeed be wrong, and I would indeed need to revisit all conclusions that followed from these assumptions. Do we have such good news? Just to be explicit, my assumptions are: Scavenging, in order to be as super efficient as it needs to be, avoids any ephemeron collection algorithm during the scavenge itself. All ephemeron collections are visited in the final atomic pause of the marking phase of a major GC cycle, which will only mark values life that still have strongly reachable keys. All others are collected by the following sweeping phase. However, if by scavenging you meant minor GC then that does not handle ephemeron collections at all. /Andreas A normal non-transposed ephemeron map implementation will promote k and v as of the second scavenge in the first scenario, which is the only safe option that postpones the ephemeron part of the gc algorithm. A normal non-transposed ephemeron map implementation will collect m and v as of the second scavenge in the second scenario, since these are collected merely by the classic scavenge without awareness of ephemeron issues. A transposed ephemeron map implementation will collect k and v as of the second scavenge in the first scenario, since these are collected merely by the classic scavenge without awareness of ephemeron issues. A transposed ephemeron map implementation will promote m and v as of the second scavenge in the second scenario, which is the only safe option that postpones the ephemeron part of the gc algorithm for transposed map
Re: Default @@toStringTag for user classes
The difference between [Object Point] and [Object Set] is fundamental. Your application would not change any behavior without explicit creating new Set. But changing behavior of existing code is something different - it can introduce subtle bugs in enclosed environment. 2 gru 2014 13:03 Claude Pache claude.pa...@gmail.com napisał(a): Le 2 déc. 2014 à 09:04, Michał Wadas michalwa...@gmail.com a écrit : It probably would be backward incompatible change. Too much code depends on [Object Object]. I'm curious to know what sort of code would be broken by `O.p.toString.call(x) === [object Point]` for instances `x` of some user-defined class? and whether it is not already broken by, say, `O.p.toString.call(new Set) === [object Set]`? —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Default @@toStringTag for user classes
I think by `@@toStringTag` he meant the ability to define a `[[Class]]` name so that `{}.toString.call(generic)` would return such name instead of `Object` but I'm sure Dmitry will come back explaining and/or asking more. On Tue, Dec 2, 2014 at 4:49 PM, Claude Pache claude.pa...@gmail.com wrote: Le 2 déc. 2014 à 08:46, Dmitry Soshnikov dmitry.soshni...@gmail.com a écrit : Hi, Probably worth providing a default implementation of the `@@toStringTag` when evaluating a class [1]. In this case users will be able to do: ``` class Point { ... } var p = new Point(1, 2); console.log(p); // [object Point] ``` You seem to imply that `console.log(p)` will show the result of `p.toString()` in the console. But it is not the case for the majority of browsers. I've just tried: ``` var Point = function() {} Point.prototype.toString = function() { return (this is an object of type Point) } console.log(new Point) ``` Results are: Firefox: Object { } Chrome: Point{toString: function} Safari: Object IE: [object Object](this is an object of type Point) In particular, note that Chrome doesn't need the help of `.toString()` in order to log useful information. —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Default @@toStringTag for user classes
From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Andrea Giammarchi I think by `@@toStringTag` he meant the ability to define a `[[Class]]` name so that `{}.toString.call(generic)` would return such name instead of `Object` but I'm sure Dmitry will come back explaining and/or asking more. [[Class]] does not appear in the spec, and @@toStringTag does. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Default @@toStringTag for user classes
From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Michal Wadas But changing behavior of existing code is something different - it can introduce subtle bugs in enclosed environment. Nobody is proposing changing the behavior of existing code. They are proposing changing the behavior of class syntax, and there is no existing code that uses class syntax. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Removal of WeakMap/WeakSet clear
On Dec 2, 2014, at 10:15 AM, Mark S. Miller wrote: Good. I think we're coming to a mutual understanding. By scavenge I mean exactly your minor collection. I think collecting typical garbage during minor collection, rather than promoting/tenuring it, is desperately important, and dominates the other efficiency considerations mentioned in this thread. Of the common scenario, you say: In a minor collection nothing is collected, because it doesn't handle ephemerons at all. which clears up my confusion from your earlier claim The very first implementation of Ephemerons we did at Digitalk was in the context of a multi-generationational ( my recollection was that it had 5 generations) scavenging collector and it did processes ephemerons at every generational level of scavenging. And quite efficiently using various remembered set tricks and other heuristics to deal with cross-generational references from ephemerons. I've always felt that the essentially two generation model that Ungar introduced (new/old space, minor/major collection, etc.) was too simplistic. It really has only two modes fast and slow (or incremental). Multiple generations are better at dealing with the wider distribution of object life times that occur in a typical application. I'm not convinced that only processing ephemerons during a major collection is a good heuristic . the value in a (map,key,value) triple can be reclaimed _immediately_ (in the same cycle) when _either_ the map _or_ the key dies. In the common scenario, as of the moment of the minor collection, the key and value are unreachable, but v8 collects neither. Instead, both are expensively promoted/tenured. Of the transposed scenario, you say: In both minor or major collection both m and v are immediately reclaimed, because neither is strongly reachable at that point which shows the asymmetry, and that v8 is effectively optimizing for the wrong side of that asymmetry. By adopting what Allen and I refer to as the transposed representation (as opposed to your transposed representation), you'd instead be able to say of the common scenario In both minor or major collection both k and v are immediately reclaimed, because neither is strongly reachable at that point which would be much more valuable than any other efficiency issue discussed in this thread. In any case, we now both understand that you can't have both at the moment of a minor collection because, as we agree, a minor collection doesn't handle ephemerons at all. You have to choose one side or the other. Why optimize for the transposed scenario rather than the common one? My main take-away from this discussion is that not have a 'clear' method on WeakMap/Set is indeed a simpler semantics and hence leaves GC designers more optimization opportunities. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Removal of WeakMap/WeakSet clear
Good point about multi-gen. Lars Hansen even researched oldest first collection: http://www.cesura17.net/~will/professional/research/presentations/gc/index.html Clearly, Ungar's model was a simplification, with trade-offs as expected. Allen Wirfs-Brock wrote: My main take-away from this discussion is that not have a 'clear' method on WeakMap/Set is indeed a simpler semantics and hence leaves GC designers more optimization opportunities. Agreed. And we can always add .clear later. The worst case, where some leading implementation (oh, say, V8) adds it sooner, just forces the conclusion. But we should not force that conclusion now, absent evidence. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Default @@toStringTag for user classes
On Tue, Dec 2, 2014 at 9:56 AM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: I think by `@@toStringTag` he meant the ability to define a `[[Class]]` name so that `{}.toString.call(generic)` would return such name instead of `Object` but I'm sure Dmitry will come back explaining and/or asking more. Yeah, so basically current `O.p.toString` [1] in step 14 delegates to the `@@toStringTag`. Which means user-classes have ability to ad-hoc the result of using _default_ `toString` from `O.p`. In a class users have to put it manually at the moment: ``` class Point { constructor(x, y) { this._x = x; this._y = y; } toString() { return 'Point ' + this._x + ', ' + this._y + ''; } [Symbol.toStringTag]() { return 'Point'; } } var p = new Point(10, 20); console.log(p.toString()); // 'Point 10, 20' console.log(({}).toString.call(p)); // '[object Point]' ``` Notice how the implementation defines its own `toString`, and at the same time provides the ability to test the type tag with the `O.p.toString`. So my proposal is to provide default implicit implementation of that `Symbol.toStringTag` method (which is `@@toStringTag` in the spec). Dmitry [1] https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring On Tue, Dec 2, 2014 at 4:49 PM, Claude Pache claude.pa...@gmail.com wrote: Le 2 déc. 2014 à 08:46, Dmitry Soshnikov dmitry.soshni...@gmail.com a écrit : Hi, Probably worth providing a default implementation of the `@@toStringTag` when evaluating a class [1]. In this case users will be able to do: ``` class Point { ... } var p = new Point(1, 2); console.log(p); // [object Point] ``` You seem to imply that `console.log(p)` will show the result of `p.toString()` in the console. But it is not the case for the majority of browsers. I've just tried: ``` var Point = function() {} Point.prototype.toString = function() { return (this is an object of type Point) } console.log(new Point) ``` Results are: Firefox: Object { } Chrome: Point{toString: function} Safari: Object IE: [object Object](this is an object of type Point) In particular, note that Chrome doesn't need the help of `.toString()` in order to log useful information. —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Default @@toStringTag for user classes
On Tue, Dec 2, 2014 at 5:12 PM, Dmitry Soshnikov dmitry.soshni...@gmail.com wrote: On Tue, Dec 2, 2014 at 9:56 AM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: I think by `@@toStringTag` he meant the ability to define a `[[Class]]` name so that `{}.toString.call(generic)` would return such name instead of `Object` but I'm sure Dmitry will come back explaining and/or asking more. Yeah, so basically current `O.p.toString` [1] in step 14 delegates to the `@@toStringTag`. Which means user-classes have ability to ad-hoc the result of using _default_ `toString` from `O.p`. In a class users have to put it manually at the moment: ``` class Point { constructor(x, y) { this._x = x; this._y = y; } toString() { return 'Point ' + this._x + ', ' + this._y + ''; } [Symbol.toStringTag]() { return 'Point'; } This one seems should be a getter actually based on the algorithm of `O.p.toString`: ``` get [Symbol.toStringTag]() { return 'Point'; } ``` Dmitry } var p = new Point(10, 20); console.log(p.toString()); // 'Point 10, 20' console.log(({}).toString.call(p)); // '[object Point]' ``` Notice how the implementation defines its own `toString`, and at the same time provides the ability to test the type tag with the `O.p.toString`. So my proposal is to provide default implicit implementation of that `Symbol.toStringTag` method (which is `@@toStringTag` in the spec). Dmitry [1] https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring On Tue, Dec 2, 2014 at 4:49 PM, Claude Pache claude.pa...@gmail.com wrote: Le 2 déc. 2014 à 08:46, Dmitry Soshnikov dmitry.soshni...@gmail.com a écrit : Hi, Probably worth providing a default implementation of the `@@toStringTag` when evaluating a class [1]. In this case users will be able to do: ``` class Point { ... } var p = new Point(1, 2); console.log(p); // [object Point] ``` You seem to imply that `console.log(p)` will show the result of `p.toString()` in the console. But it is not the case for the majority of browsers. I've just tried: ``` var Point = function() {} Point.prototype.toString = function() { return (this is an object of type Point) } console.log(new Point) ``` Results are: Firefox: Object { } Chrome: Point{toString: function} Safari: Object IE: [object Object](this is an object of type Point) In particular, note that Chrome doesn't need the help of `.toString()` in order to log useful information. —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss