C. Scott Ananian (2015-04-29T21:36:50.000Z)
d at domenic.me (2015-05-11T16:50:16.777Z)
On Wed, Apr 29, 2015 at 4:16 PM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote: > the last two lines of the above `resolve` method should be replaced with: > ```js > return super.resolve(x) > ``` > `x.construct === this` is the test that I propose Promise.resolve should > make instead of testing [[PromiseConstructor]] > There should probably also be another test that > SpeciesConstructor(x)===this > This is still not correct. You can't call `super.resolve(x)` safely unless you know that this.constructor is trustworthy. If you've bailed out of the `switch`, you don't know that. A correct implementation just does `return new this(r => { r(x); })` after the switch. The "another test" that you propose seems to be exactly the fix which Brandon proposed and I codified, to wit: ``` 2. If IsPromise(x) is true, a. Let constructor be the value of SpeciesConstructor(x, %Promise%) b. If SameValue(constructor, C) is true, return x. ``` > I wouldn't jump the gun until we actually have TC39 consensus on a proposal. Mark, after you've slept on this and assuming you haven't changed your mind, would you be willing to be the TC39 champion? I'm not a participant in that process. > What we've shown is that the [[PromiseConstructor]] test was never > sufficient to guarantee the invariant that Mark is concerned about and also > that there probably isn't a generic check we can do that would satisfy his > requirements. He has do it himself like shown above. But the specified > [[PromiseConstructor]] test doesn't really hurt anything. It places some > slight limitations on what subclasses can do, but probably doesn't > interfere with anything an actual subclass is likely to do. It seems like > a restriction than can be relaxed in the future without anybody (or than > conformance tests) noticing. > Well, the [[PromiseConstructor]] test is breaking `prfun`, `es6-shim` and `core-js` right now, which is why I noticed it in the first place. (v8 seems to have implemented the `[[PromiseConstructor]]` internal property even though they don't have `new.target` implemented, so it's always hard-wired to `Promise`.) And `babel` and `core-js` have implemented non-standard semantics for `Promise.resolve` as a result. In particular, with the current state of `Promise.resolve`, I can't subclass `Promise` in a meaningful way using ES5 syntax (see, the thread title turns relevant again!). So I have a vested interest in getting the semantics fixed so that people can start using `Promise` subclasses (like `prfun` does) instead of writing their "extra" Promise helpers directly on the `Promise` global object, while we're all waiting for ES6 syntax to make it to the mainstream. (And when I say "getting the semantics fixed" what I really mean is "consensus among TC39" so that shim libraries can implement the correct semantics as early adopters, with assurance the browser engines will follow.) Since I believe the goal is to eventually introduce some new methods on the global `Promise` in ES7, I think this list would have a keen interest in ensuring that libraries which stomp on the global Promise (due to lack of an alternative) don't take root.