Re: Existential Operator / Null Propagation Operator
On Tue, Jun 2, 2015 at 1:31 PM, Sander Deryckere sander...@gmail.com wrote: 2015-06-02 18:57 GMT+02:00 Brendan Eich bren...@mozilla.org: You might hope for that, but as we both noted, `?[` is not going to fly. Don't break the (minified) Web. Which is why my proposal was about `??`. I believe there's currently no valid way to use a double question mark in JS, so even `??[` should be easy to figure out what it means. The prefix idea generalizes: ?obj[key] obj[?key] obj[key1][?key2] and if you are not using computed property names, rather literal ones: obj.?prop1 etc. I found this syntax to conflict with itself. As Andreas Rossberg says, what does `orders[?client.key].price` mean? Does it mean check if the client exists, and if not, return the price of the null order, or does it mean check if the order for this client exists, and return null if it doesn't? I don't see a way how both meanings can be made possible with this form of prefix notation. Um, if I'm reading Brenden correctly, neither? check if the client exists, and if not, return the price of the null order === orders[client.?key].price check if the order for this client exists, and return null if it doesn't === orders[client.key].?price I would suggest a third interpretation for `orders[?client.key].price`: === (orders ? orders[client.key] : null).price I think that the problem here isn't that it is ambiguous, it is that it isn't obvious. Something that might be more obvious but requires an additional character: `orders.?[client.key].price`. More precisely, the suggestion is to standardize on .? and allow it to be followed by either a simple name, a square bracket, or a left paren. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss - Sam Ruby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential Operator / Null Propagation Operator
Sam Ruby wrote: I think that the problem here isn't that it is ambiguous, it is that it isn't obvious. Fair point! Something that might be more obvious but requires an additional character: `orders.?[client.key].price`. That's not bad. The whole proposal may founder, though, on grawlix objections. And some still want the ?obj.foo.bar to soak null/undefined obj and missing foo or null/undefined value of foo. CoffeeScript fans for sure, but it's in principle and practice at least as valid a use-case as obj.?foo is. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fixing `Promise.resolve()`
Thanks! It looks like core-js has already patched in the new spec: https://github.com/zloirock/core-js/issues/75 I've opened https://github.com/paulmillr/es6-shim/issues/344 on es6-shim, and I'll see if I can get a patch together for it. I've filed https://bugzilla.mozilla.org/show_bug.cgi?id=1170742 against Mozilla. I've filed https://code.google.com/p/v8/issues/detail?id=4161 against v8. Allen: Will this be an errata to ES6, part of ES7, or something else? --scott ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Maybe we need a reflect API to iterate over instance members
2015-06-01 20:36 GMT+02:00 Alexander Jones a...@weej.com: On Monday, June 1, 2015, Tom Van Cutsem tomvc...@gmail.com wrote: Or since Proxy traps correspond 1-to-1 to the internal methods in the spec, the primary goal of the Reflect API was to expose the essential methods that make up Javascript's object model as defined by the spec. I like this definition. Is it written down? (I need ammunition for Reflect.type(x)!) There's some rationale on the original wiki page for the reflect API: http://wiki.ecmascript.org/doku.php?id=harmony:reflect_api#purpose. We also had a related short debate on this list 3 months ago, see https://esdiscuss.org/topic/reflect-getownpropertysymbols#content-0, in particular, Allen's comment: In ES6, the primary role of the Reflect object is to provide direct access to an object's essential internal methods. Regards, Tom ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: How can I synchronously determine a JavaScript Promise's state? (Domenic Denicola)
Apologies if this is a duplicate: I'm new to mailing lists and got a little bit muddled. ## legacy use case I am maintaining an existing API that includes asynchronous functions (mix of callbacks and Promises) and synchronous functions. After some asynchronous initialisation, the internal state settles and it is perfectly safe to use the synchronous functions as expected. So, I'd like to emit warnings when these synchronous functions are called prior to a Promise being settled. That way, downstream developers will know that they should be waiting for the Promise to settle before using such functions. This actually isn't too different to the XHR / Fetch APIs conceptually. We get the ball rolling with an asynchronous API call, but there are deterministic blocks within which we can synchronously interrogate progress, etc. ## activity indicator use case I use a Promise to represent a network transaction. I wish to alter the visual state of my web app to reflect the state of this network transaction. I can, for example, show an indeterminate progress bar whilst the Promise is not settled. If I am using requestAnimationFrame, or a framework like React, then the state would be synchronously mapped to the DOM / canvas during each execution of my render function. I can track the state of the Promise using additional variables (as others have suggested), but those state values already exist somewhere private per the functioning of a Promise. I'd be duplicating work that the JavaScript engine is already performing internally, at the risk of introducing errors in my code. ## third-party popular libraries The following libraries implement some form of Promise and all expose such synchronous inspection capabilities: - jQuery: http://api.jquery.com/deferred.state/ - Bluebird: https://github.com/petkaantonov/bluebird/blob/master/API.md#synchronous-inspection - Q: https://github.com/kriskowal/q/wiki/API-Reference#state-inspection-methods - Lie: https://github.com/calvinmetcalf/lie/blob/master/lib/promise.js#L17 On Tue, 2 Jun 2015 at 07:31 Domenic Denicola d...@domenic.me wrote: I will repeat to you what I said on Specifiction: To get a standard API for this, you'll need to convince the JavaScript standard committee, as well as the browser vendors, that your use case is widespread and important enough to be worth the standardization and implementation burden, and that it cannot be achieved in any other possible way. So ... go! Looking forward to your use cases, preferably with examples showing code in popular libraries or apps that would benefit to illustrate how wide-spread those use cases are. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fixing `Promise.resolve()`
Hi Scott, If the change is as simple as it appears, it seems it will go into ES6 itself! Thanks for pushing this forward. On Tue, Jun 2, 2015 at 1:25 PM, C. Scott Ananian ecmascr...@cscott.net wrote: Thanks! It looks like core-js has already patched in the new spec: https://github.com/zloirock/core-js/issues/75 I've opened https://github.com/paulmillr/es6-shim/issues/344 on es6-shim, and I'll see if I can get a patch together for it. I've filed https://bugzilla.mozilla.org/show_bug.cgi?id=1170742 against Mozilla. I've filed https://code.google.com/p/v8/issues/detail?id=4161 against v8. Allen: Will this be an errata to ES6, part of ES7, or something else? --scott -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Reflect.type
For some strange reason esdiscuss.org has garbled that link! For the benefit of those readers: https://github.com/alex-weej/es-reflect-type-proposal (Apologies for spam) On 2 June 2015 at 23:10, Alexander Jones a...@weej.com wrote: I've written this up as a strawman. It's available at https://github.com/alex-weej/es-reflect-type-proposal Thanks On 15 May 2015 at 00:37, Alexander Jones a...@weej.com wrote: I'm sure there will evolve some other nomenclature for that in due course. From http://www.slideshare.net/BrendanEich/value-objects2 it sounds as if it would be reasonable to define `Type(x)` to be `Value`, and thus `Reflect.type(x)` to be `Reflect.types.value`. Agree with the Symbol labels. On 14 May 2015 at 18:50, Andrea Giammarchi andrea.giammar...@gmail.com wrote: FWIW, I think whatever contains type in modern JS should consider `int32`, `float64`, and all TypedArrays plus it would be awesome to have a way to define own types. In any case, if your idea will be implemented, I think it should have named Symbols for debugging sake. ```js Symbol('undefined'), Symbol('null'), Symbol('boolean') ``` This would be at least consistent with current implementations of `Symbol.iterator` and friends. Best Regards On Thu, May 14, 2015 at 5:29 PM, Alexander Jones a...@weej.com wrote: Just an idea, if it doesn't already exist somewhere. Reflect.type(x) would match the spec's Type(x) function, in that it would basically be a better, more convenient typeof, i.e. Reflect.types = { undefined: Symbol(), null: Symbol(), boolean: Symbol(), string: Symbol(), symbol: Symbol(), number: Symbol(), object: Symbol(), } Reflect.type(null) === Reflect.types.null Reflect.type(function() {}) === Reflect.types.object We weren't able to fix typeof null in harmony, but this seems like a good opportunity to introduce something new. Haven't thought about the repercussions of future support for new value types... Any thoughts? ___ 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: Reflect.type
I've written this up as a strawman. It's available at https://github.com/alex-weej/es-reflect-type-proposal Thanks On 15 May 2015 at 00:37, Alexander Jones a...@weej.com wrote: I'm sure there will evolve some other nomenclature for that in due course. From http://www.slideshare.net/BrendanEich/value-objects2 it sounds as if it would be reasonable to define `Type(x)` to be `Value`, and thus `Reflect.type(x)` to be `Reflect.types.value`. Agree with the Symbol labels. On 14 May 2015 at 18:50, Andrea Giammarchi andrea.giammar...@gmail.com wrote: FWIW, I think whatever contains type in modern JS should consider `int32`, `float64`, and all TypedArrays plus it would be awesome to have a way to define own types. In any case, if your idea will be implemented, I think it should have named Symbols for debugging sake. ```js Symbol('undefined'), Symbol('null'), Symbol('boolean') ``` This would be at least consistent with current implementations of `Symbol.iterator` and friends. Best Regards On Thu, May 14, 2015 at 5:29 PM, Alexander Jones a...@weej.com wrote: Just an idea, if it doesn't already exist somewhere. Reflect.type(x) would match the spec's Type(x) function, in that it would basically be a better, more convenient typeof, i.e. Reflect.types = { undefined: Symbol(), null: Symbol(), boolean: Symbol(), string: Symbol(), symbol: Symbol(), number: Symbol(), object: Symbol(), } Reflect.type(null) === Reflect.types.null Reflect.type(function() {}) === Reflect.types.object We weren't able to fix typeof null in harmony, but this seems like a good opportunity to introduce something new. Haven't thought about the repercussions of future support for new value types... Any thoughts? ___ 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: Promise sub-class: super((resolve, reject) = this) ?
This is a limitation of Babel and not at all a reflection of the actual specification. This restriction is imposed order to follow ES2015 semantics of not being able to reference `this` before `super()`. It does a pretty dumb check of only allowing it to be strictly after the call (ie. not before or inside it). Note that this is also the behaviour of Traceur and TypeScript so Babel is not alone with this decision. You can see extensive discussion of this in the issue: https://github.com/babel/babel/issues/1131 On Tue, Jun 2, 2015 at 11:36 PM, Matthew Robb matthewwr...@gmail.com wrote: I was trying to demonstrate a simple method of exposing resolve and reject functions to someone and noticed in Babel at least you cannot do this. It seems as though in this case when the arrow function is called it will have been AFTER the call to super. Can someone help me understand what's going on here? - Matthew Robb___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fixing `Promise.resolve()`
On Jun 2, 2015, at 2:01 PM, Mark S. Miller wrote: Hi Scott, If the change is as simple as it appears, it seems it will go into ES6 itself! The fix has already been made to the production copy that will be released in a couple weeks when we have ECMA GA approval Allen Thanks for pushing this forward. On Tue, Jun 2, 2015 at 1:25 PM, C. Scott Ananian ecmascr...@cscott.net wrote: Thanks! It looks like core-js has already patched in the new spec: https://github.com/zloirock/core-js/issues/75 I've opened https://github.com/paulmillr/es6-shim/issues/344 on es6-shim, and I'll see if I can get a patch together for it. I've filed https://bugzilla.mozilla.org/show_bug.cgi?id=1170742 against Mozilla. I've filed https://code.google.com/p/v8/issues/detail?id=4161 against v8. Allen: Will this be an errata to ES6, part of ES7, or something else? --scott -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Promise sub-class: super((resolve, reject) = this) ?
I was trying to demonstrate a simple method of exposing resolve and reject functions to someone and noticed in Babel at least you cannot do this. It seems as though in this case when the arrow function is called it will have been AFTER the call to super. Can someone help me understand what's going on here? - Matthew Robb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Promise sub-class: super((resolve, reject) = this) ?
Hmm I am pretty sure Babel et al. are correct here in not allowing this. The super call needs to *finish* before you can use `this`. Chrome also works this way. The correct workaround is ```js let resolve, reject; super((a, b) = { resolve = a; reject = b; }); // use this ``` ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Promise sub-class: super((resolve, reject) = this) ?
Ah, completely right. At first glance I thought it was this similar but separate issue: ```js class Foo { constructor(callback) { this.callback = callback; // just storing it! } } class Bar extends Foo { constructor() { super(() = this); // reference to `this` will throw since the behaviour of the super class can’t be easily inferred } } ``` Shifting runtime errors to compile time isn’t always the most reliable. On Tue, Jun 2, 2015 at 11:43 PM, Domenic Denicola d...@domenic.me wrote: Hmm I am pretty sure Babel et al. are correct here in not allowing this. The super call needs to *finish* before you can use `this`. Chrome also works this way. The correct workaround is ```js let resolve, reject; super((a, b) = { resolve = a; reject = b; }); // use this ```___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Promise sub-class: super((resolve, reject) = this) ?
If I thought I could make any money then I would most definitely bet that the changes made to classes that are at the root of this problem will be the undoing of es classes and I find myself feeling more and more like avoiding them is the easiest thing to do. This use-case is a perfect example of something that is EXTREMELY unexpected which is funny because the changes are supposed to be supporting subclassing of built-ins. Very disheartened :( - Matthew Robb On Tue, Jun 2, 2015 at 6:43 PM, Domenic Denicola d...@domenic.me wrote: Hmm I am pretty sure Babel et al. are correct here in not allowing this. The super call needs to *finish* before you can use `this`. Chrome also works this way. The correct workaround is ```js let resolve, reject; super((a, b) = { resolve = a; reject = b; }); // use this ``` ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
When should we define a function as async
I asked it on StackOverflow but they say it is not best fit for SO, so I tried to get some help here If one of my function: Returns a promise Do not need to await any other functions Do not create promise itself, it just return a promise returned by another function Do not call then or catch on promises so it does not involve further async flows Should this function be async? For example: async function updateUser(user) { return await fetch('/some/url', {body: JSON.stringify(data)}); } function growUp1(user) { user.age++; return updateUser(user); } async function growUp2(user) { user.age++; return await updateUser(user); } I think the growUp1 is more simple and have neater code with better performance after babel transformation (since less async generators are involved), and growUp2 is more robust when updateUser switches between async and sync. Should we possibly enforce: If a function is returning Promise, it MUST be async If a function depends on an async function, it **MUST be async A further question could be, if one function only contains some simple then calls to promise, should it become an async function and use await in all possible cases to eliminate then calls? Best regards Gray Zhang ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Promise sub-class: super((resolve, reject) = this) ?
To clarify things, since I don't think it's been made abundantly clear, the example that Sebastian gave would work in a standard ES6 environment, correct? It is only if the callback were executed synchronously that the exception would be thrown since the `this` binding has not yet been initialized? Transpilers however have elected to prevent this to err on the side of ensuring that invalid ES6 allowed through because adding runtime checking for the `this` binding would be difficult? On Tue, Jun 2, 2015 at 7:37 PM, Brendan Eich bren...@mozilla.org wrote: With best intentions I must say that you are overreacting. The subject-line code (h/t Mark Miller for pointing me at it!) in context of the superclass constructor uses `this` before `super` has returned. That's a no-no for pretty-good reason. If you have a better alternative design, we needed it last month. As things stand, this is a thing to learn, with a workaround. What's the big deal? /be Matthew Robb wrote: If I thought I could make any money then I would most definitely bet that the changes made to classes that are at the root of this problem will be the undoing of es classes and I find myself feeling more and more like avoiding them is the easiest thing to do. This use-case is a perfect example of something that is EXTREMELY unexpected which is funny because the changes are supposed to be supporting subclassing of built-ins. Very disheartened :( - Matthew Robb On Tue, Jun 2, 2015 at 6:43 PM, Domenic Denicola d...@domenic.me mailto: d...@domenic.me wrote: Hmm I am pretty sure Babel et al. are correct here in not allowing this. The super call needs to *finish* before you can use `this`. Chrome also works this way. The correct workaround is ```js let resolve, reject; super((a, b) = { resolve = a; reject = b; }); // use this ``` ___ 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 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Promise sub-class: super((resolve, reject) = this) ?
Hi Logan - that's correct. On Tue, Jun 2, 2015 at 11:08 PM Logan Smyth loganfsm...@gmail.com wrote: To clarify things, since I don't think it's been made abundantly clear, the example that Sebastian gave would work in a standard ES6 environment, correct? It is only if the callback were executed synchronously that the exception would be thrown since the `this` binding has not yet been initialized? Transpilers however have elected to prevent this to err on the side of ensuring that invalid ES6 allowed through because adding runtime checking for the `this` binding would be difficult? On Tue, Jun 2, 2015 at 7:37 PM, Brendan Eich bren...@mozilla.org wrote: With best intentions I must say that you are overreacting. The subject-line code (h/t Mark Miller for pointing me at it!) in context of the superclass constructor uses `this` before `super` has returned. That's a no-no for pretty-good reason. If you have a better alternative design, we needed it last month. As things stand, this is a thing to learn, with a workaround. What's the big deal? /be Matthew Robb wrote: If I thought I could make any money then I would most definitely bet that the changes made to classes that are at the root of this problem will be the undoing of es classes and I find myself feeling more and more like avoiding them is the easiest thing to do. This use-case is a perfect example of something that is EXTREMELY unexpected which is funny because the changes are supposed to be supporting subclassing of built-ins. Very disheartened :( - Matthew Robb On Tue, Jun 2, 2015 at 6:43 PM, Domenic Denicola d...@domenic.me mailto: d...@domenic.me wrote: Hmm I am pretty sure Babel et al. are correct here in not allowing this. The super call needs to *finish* before you can use `this`. Chrome also works this way. The correct workaround is ```js let resolve, reject; super((a, b) = { resolve = a; reject = b; }); // use this ``` ___ 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 ___ 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: Promise sub-class: super((resolve, reject) = this) ?
With best intentions I must say that you are overreacting. The subject-line code (h/t Mark Miller for pointing me at it!) in context of the superclass constructor uses `this` before `super` has returned. That's a no-no for pretty-good reason. If you have a better alternative design, we needed it last month. As things stand, this is a thing to learn, with a workaround. What's the big deal? /be Matthew Robb wrote: If I thought I could make any money then I would most definitely bet that the changes made to classes that are at the root of this problem will be the undoing of es classes and I find myself feeling more and more like avoiding them is the easiest thing to do. This use-case is a perfect example of something that is EXTREMELY unexpected which is funny because the changes are supposed to be supporting subclassing of built-ins. Very disheartened :( - Matthew Robb On Tue, Jun 2, 2015 at 6:43 PM, Domenic Denicola d...@domenic.me mailto:d...@domenic.me wrote: Hmm I am pretty sure Babel et al. are correct here in not allowing this. The super call needs to *finish* before you can use `this`. Chrome also works this way. The correct workaround is ```js let resolve, reject; super((a, b) = { resolve = a; reject = b; }); // use this ``` ___ 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:Existential Operator / Null Propagation Operator
(I hope this arrives in the right thread, it's meant as a reply for https://esdiscuss.org/topic/existential-operator-null-propagation-operator ) I very much like the proposal, our JS code is full with cases where certain components can be null, but we need to execute an action with the component when it's not null. However, the collisions with existing syntax is indeed troublesome. So far, I liked the `?.`, `?[` and `?(` operators the most. But what should be done with cases like `obj?[1]?[2]:[3]`. Does it test `obj?[1]` and returns `[2]` or `[3]` depending on the result, or does it test `obj` and return `[1]?[2]` or `[3]` depending on the result. A similar case with functions: `func1?(func2)?(func3):(func4)`. Does it test `func1?(func2)`, or can it return `(func2)?(func3)`? Both cases depend on the binding to the `:` of the ternary operator. Which might cause too many changes to the spec, and too many exceptions to keep the language compatible. The `.?` operator seems to have no alternative for variable keys (`obj[key]`), which is IMO the most usefull use-case (testing explicitly for null is most likely to happen when you don't know a lot about the object when writing the code, so likely you also don't know the key). As such `.?` isn't an option for me. For the prefix operator, it's unclear to me how you would do the following: Say you know `obj` is non-null, you want to test if it has a key `k1`, but if `k1` exists, you know it will also have a key `k2` a level deeper. With the suffix operator, this would be `obj[k1]?[k2]`, but with the prefix operator, it could be `obj?[k1][k2]` (which again has the same problems as first described with the `?[` operator), while it could also be `obj[?k1][k2]` (which even conflicts with itself, as it could also test if `k1` as a variable is non-null). As such, all these proposals have at least as many issues as `?.`. And `?.` already has too many issues to implement it. So, I'd like to propose another operator: `??` (with `??[` and `??(`) In current syntax, the `?` is only used for the ternary operator, and requires something else before and after it. Which means that any code that has `??` is currently invalid. We currently sometimes use the logical to test nullness of a value, and access its properties. Like: `var result = obj obj.key;` Which tests if `obj` exists (assuming obj is an object when defined), and returns `obj.key` if it does. With the `??` operator, it can be simplified to `var result = obj??key;` Combined with `arr??[idx]` and `func??(arg)`, I think this will work very fine. Regards, Sander ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Actual WeakSet Use Cases
You could use it to avoid bugs involving circular references when iterating, for example: ```js function iterate(O, fn) { if (O == null) return O; let objects = new WeakSet(); iterate_inner(‘’, O, objects, fn); return O; function iterate_inner(name, O, objects, fn) { for (let key of Reflect.ownKeys(O)) { let value = O[key]; let niceName = name ? `${name}.${key}` : key; if (typeof value === “object” value) { // Avoid recursing into circular reference if (objects.has(value)) { continue; } else { fn(value, niceName); objects.add(value); iterate_inner(niceName, value, objects, fn); } } else { fn(value, niceName); } } } } ``` On Jun 2, 2015, at 11:14 AM, Domenic Denicola d...@domenic.me wrote: WeakSets are perfect for branding and are how I would expect web platform class branding to be explained. ```js const foos = new WeakSet(); class Foo { constructor() { foos.add(this); } method() { if (!foos.has(this)) { throw new TypeError(Foo.prototype.method called on an incompatible object!); } } } ``` ___ 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: Actual WeakSet Use Cases
Caitlin, in that example a normal Set works just as well. It can get gc'ed when you leave the iterate function. On Tue, Jun 2, 2015, 11:25 Caitlin Potter caitpotte...@gmail.com wrote: You could use it to avoid bugs involving circular references when iterating, for example: ```js function iterate(O, fn) { if (O == null) return O; let objects = new WeakSet(); iterate_inner(‘’, O, objects, fn); return O; function iterate_inner(name, O, objects, fn) { for (let key of Reflect.ownKeys(O)) { let value = O[key]; let niceName = name ? `${name}.${key}` : key; if (typeof value === “object” value) { // Avoid recursing into circular reference if (objects.has(value)) { continue; } else { fn(value, niceName); objects.add(value); iterate_inner(niceName, value, objects, fn); } } else { fn(value, niceName); } } } } ``` On Jun 2, 2015, at 11:14 AM, Domenic Denicola d...@domenic.me wrote: WeakSets are perfect for branding and are how I would expect web platform class branding to be explained. ```js const foos = new WeakSet(); class Foo { constructor() { foos.add(this); } method() { if (!foos.has(this)) { throw new TypeError(Foo.prototype.method called on an incompatible object!); } } } ``` ___ 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 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Actual WeakSet Use Cases
WeakSets are perfect for branding and are how I would expect web platform class branding to be explained. ```js const foos = new WeakSet(); class Foo { constructor() { foos.add(this); } method() { if (!foos.has(this)) { throw new TypeError(Foo.prototype.method called on an incompatible object!); } } } ``` ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Actual WeakSet Use Cases
So umm... not to be annoying but I've been digging through esdiscuss and various blog posts online. I couldn't really find any use case for WeakSet (plenty of threads about naming things :P). Most material about it online fails to distinguish it from what one would use a regular Set for. All the use cases I know for `WeakSet` for tagging objects aren't really relevant in JS (for example - in shared memory threading scenarios). Can someone show me a convincing actual use case for WeakSet that can't better be solved without it? Thanks, and sorry, Benjamin ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Actual WeakSet Use Cases
Yes, we had that discussion on #whatwg already, I haven’t had my coffee yet =) On Jun 2, 2015, at 11:33 AM, Erik Arvidsson erik.arvids...@gmail.com wrote: Caitlin, in that example a normal Set works just as well. It can get gc'ed when you leave the iterate function. On Tue, Jun 2, 2015, 11:25 Caitlin Potter caitpotte...@gmail.com mailto:caitpotte...@gmail.com wrote: You could use it to avoid bugs involving circular references when iterating, for example: ```js function iterate(O, fn) { if (O == null) return O; let objects = new WeakSet(); iterate_inner(‘’, O, objects, fn); return O; function iterate_inner(name, O, objects, fn) { for (let key of Reflect.ownKeys(O)) { let value = O[key]; let niceName = name ? `${name}.${key}` : key; if (typeof value === “object” value) { // Avoid recursing into circular reference if (objects.has(value)) { continue; } else { fn(value, niceName); objects.add(value); iterate_inner(niceName, value, objects, fn); } } else { fn(value, niceName); } } } } ``` On Jun 2, 2015, at 11:14 AM, Domenic Denicola d...@domenic.me mailto:d...@domenic.me wrote: WeakSets are perfect for branding and are how I would expect web platform class branding to be explained. ```js const foos = new WeakSet(); class Foo { constructor() { foos.add(this); } method() { if (!foos.has(this)) { throw new TypeError(Foo.prototype.method called on an incompatible object!); } } } ``` ___ es-discuss mailing list es-discuss@mozilla.org mailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org mailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential Operator / Null Propagation Operator
Sander Deryckere wrote: For the prefix operator, it's unclear to me how you would do the following: Say you know `obj` is non-null, you want to test if it has a key `k1`, but if `k1` exists, you know it will also have a key `k2` a level deeper. With the suffix operator, this would be `obj[k1]?[k2]`, but with the prefix operator, it could be `obj?[k1][k2]` You circled back to the incompatible syntax, `?[`, but the prefix idea would have `?obj[k1][k2]`. The `?` goes in front at the start of an operand, and is thus unambiguous with respect to the ternary operator. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Actual WeakSet Use Cases
Thanks Domenic, Elaborating on your example with more details. Let's say you need to make sure at a certain point that an object has not been tinkered with by user code (for security reasons). You can't check the prototype or a symbol since those can be faked and you can't keep a regular `Set` because that would prevent any `Foo` object from ever being garbage collected. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Actual WeakSet Use Cases
On Tue, Jun 2, 2015 at 8:45 AM, Benjamin Gruenaum benjami...@gmail.com wrote: Thanks Domenic, Elaborating on your example with more details. Let's say you need to make sure at a certain point that an object has not been tinkered with by user code (for security reasons). You can't check the prototype or a symbol since those can be faked and you can't keep a regular `Set` because that would prevent any `Foo` object from ever being garbage collected. Exactly. WeakSet's use-cases are all in the same family as WeakMap, just with a simpler set-up - rather than associating arbitrary data with the object, you just associate is in this set with it. ~TJ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential Operator / Null Propagation Operator
2015-06-02 17:49 GMT+02:00 Brendan Eich bren...@mozilla.org: Sander Deryckere wrote: For the prefix operator, it's unclear to me how you would do the following: Say you know `obj` is non-null, you want to test if it has a key `k1`, but if `k1` exists, you know it will also have a key `k2` a level deeper. With the suffix operator, this would be `obj[k1]?[k2]`, but with the prefix operator, it could be `obj?[k1][k2]` You circled back to the incompatible syntax, `?[`, but the prefix idea would have `?obj[k1][k2]`. The `?` goes in front at the start of an operand, and is thus unambiguous with respect to the ternary operator. The question is not about the existence of `obj`, but if `obj` has a key `k1`. AFAICS, `?obj[k1][k2]` would test the existence of `obj`, which I don't need in this example. To test the existence of a key inside `obj`, a prefix operator should come somewhere before the key. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential Operator / Null Propagation Operator
Sander Deryckere wrote: 2015-06-02 17:49 GMT+02:00 Brendan Eich bren...@mozilla.org mailto:bren...@mozilla.org: Sander Deryckere wrote: For the prefix operator, it's unclear to me how you would do the following: Say you know `obj` is non-null, you want to test if it has a key `k1`, but if `k1` exists, you know it will also have a key `k2` a level deeper. With the suffix operator, this would be `obj[k1]?[k2]`, but with the prefix operator, it could be `obj?[k1][k2]` You circled back to the incompatible syntax, `?[`, but the prefix idea would have `?obj[k1][k2]`. The `?` goes in front at the start of an operand, and is thus unambiguous with respect to the ternary operator. The question is not about the existence of `obj`, but if `obj` has a key `k1`. AFAICS, `?obj[k1][k2]` would test the existence of `obj`, which I don't need in this example. To test the existence of a key inside `obj`, a prefix operator should come somewhere before the key. You might hope for that, but as we both noted, `?[` is not going to fly. Don't break the (minified) Web. The prefix idea generalizes: ?obj[key] obj[?key] obj[key1][?key2] and if you are not using computed property names, rather literal ones: obj.?prop1 etc. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential Operator / Null Propagation Operator
On 2 June 2015 at 18:57, Brendan Eich bren...@mozilla.org wrote: Sander Deryckere wrote: 2015-06-02 17:49 GMT+02:00 Brendan Eich bren...@mozilla.org mailto: bren...@mozilla.org: Sander Deryckere wrote: For the prefix operator, it's unclear to me how you would do the following: Say you know `obj` is non-null, you want to test if it has a key `k1`, but if `k1` exists, you know it will also have a key `k2` a level deeper. With the suffix operator, this would be `obj[k1]?[k2]`, but with the prefix operator, it could be `obj?[k1][k2]` You circled back to the incompatible syntax, `?[`, but the prefix idea would have `?obj[k1][k2]`. The `?` goes in front at the start of an operand, and is thus unambiguous with respect to the ternary operator. The question is not about the existence of `obj`, but if `obj` has a key `k1`. AFAICS, `?obj[k1][k2]` would test the existence of `obj`, which I don't need in this example. To test the existence of a key inside `obj`, a prefix operator should come somewhere before the key. You might hope for that, but as we both noted, `?[` is not going to fly. Don't break the (minified) Web. The prefix idea generalizes: ?obj[key] obj[?key] obj[key1][?key2] Hm, what's the meaning of a[?b[c]] ? /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential Operator / Null Propagation Operator
2015-06-02 18:57 GMT+02:00 Brendan Eich bren...@mozilla.org: You might hope for that, but as we both noted, `?[` is not going to fly. Don't break the (minified) Web. Which is why my proposal was about `??`. I believe there's currently no valid way to use a double question mark in JS, so even `??[` should be easy to figure out what it means. The prefix idea generalizes: ?obj[key] obj[?key] obj[key1][?key2] and if you are not using computed property names, rather literal ones: obj.?prop1 etc. I found this syntax to conflict with itself. As Andreas Rossberg says, what does `orders[?client.key].price` mean? Does it mean check if the client exists, and if not, return the price of the null order, or does it mean check if the order for this client exists, and return null if it doesn't? I don't see a way how both meanings can be made possible with this form of prefix notation. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss