<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">Inadvertently moved discussion off-list; requoting on list:</div><div class="gmail_quote"><br></div><div class="gmail_quote">On Sat, Apr 25, 2015 at 4:33 PM, Domenic Denicola <span dir="ltr"><<a href="mailto:d@domenic.me" target="_blank">d@domenic.me</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">From: es-discuss [mailto:<a href="mailto:es-discuss-bounces@mozilla.org">es-discuss-bounces@mozilla.org</a>] On Behalf Of C. Scott Ananian<br>
<span class=""><br>
> But in the code given previously, I've used `Object.setPrototypeOf` to effectively change the type of the object -- but [[PromiseConstructor]] doesn't follow along.<br>
<br>
</span>That is exactly the kind of tampering that the unforgable [[PromiseConstructor]] mechanism is meant to prevent.<br></blockquote><div><br></div><div>Sure, but why? If it is now quacking like a duck, returning it from GoosePromise.resolve as if it were still a goose seems wrong.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Because then you could break invariants by doing e.g. `var syncThenable = { then(f) { f(5); }; syncThenable.constructor = Promise`.<br>
</blockquote></div><br></div><div class="gmail_extra">Oh, I don't think looking at the constructor is right, either.  It seems you should perhaps be looking at the object's prototype chain instead, like instanceof does.<br></div><div class="gmail_extra"><div class="gmail_extra"><br></div><div class="gmail_extra">The invariant I expect to be preserved is that `GoosePromise.resolve(x)` gives me a `GoosePromise` back, regardless of what sort of `x` I give it.  But instead if I give it an `x` which *used to be* a goose but is now a duck, I get back a duck instead of a goose.</div><div class="gmail_extra"><br></div><div class="gmail_extra">And this is a real use case: my `prfun` package creates a `BoundPromise` subclass, but because I'm doing it ES5 style without access to `new.target`, `Promise.resolve(x)` returns a `BoundPromise` (and `BoundPromise.resolve(x)` returns a `Promise`) because everything "was once a Promise".</div><div class="gmail_extra"><br></div><div class="gmail_extra">This particular case will probably be less frequent once we can do "real" subclassing in JavaScript engines... but it still seems to indicate to me that this basic idea is broken.  What things "once were" seems to be some weird property with no resemblance to what they are now.</div><div class="gmail_extra">  --scott</div></div></div>