Fixing `Promise.resolve()`

Domenic Denicola d at
Wed Jun 10 15:40:10 UTC 2015

Yes, I read that thread and still stand by my position.

From: cananian at [mailto:cananian at] On Behalf Of C. Scott Ananian
Sent: Wednesday, June 10, 2015 11:39
To: Domenic Denicola
Cc: Allen Wirfs-Brock; Axel Rauschmayer; Mark S. Miller; es-discuss list
Subject: Re: Fixing `Promise.resolve()`

@Domenic: please see the previous discussion at since there is much more discussion back-and-forth there.

And you are correct about Promise.reject; Allen is proposing to remove the @@species from that method as well.

The changes to `Promise.resolve` are needed to make other use cases work properly (see that other thread).  It seems that your particular use case could be better handled by overriding `LabelledPromise.resolve` to take an additional "label" argument.

Your understanding of @@species seems to be different from the use cases envisioned by the smalltalk concept named species, although it's an interesting idea in its own right.  You should probably call it something like "custom constructors", though, to differentiate it from the smalltalk "species", which is used in the smalltalk world to describe two related things (1) the "generic type" of the object, for type tests, and (2) the "derived type" which instance-transformation methods should yield.[*]  In smalltalk (as I understand it) custom constructors are not part of the design.

[*] ""Answer the preferred class for reconstructing the receiver. For example,  collections create new collections whenever enumeration messages such as collect: or select: are invoked. The new kind of collection is determined by the species of the original collection. Species and class are not always the  same. For example, the species of Interval is Array."

On Wed, Jun 10, 2015 at 11:22 AM, Domenic Denicola <d at<mailto:d at>> wrote:
Allen, that change seems wrong. I thought we were only changing the IsPromise steps. The actual construction should still go through species. If nothing else, it should do so for consistency with reject.

The motivation of @@species, as I understood it, was to allow alternate subclass constructor signatures (originally for Array and TypedArray, but Promise can benefit as well). It’s understandable to not involve @@species when doing weak type-tests. But any time you construct a promise instance, you should go through @@species, instead of the constructor directly.

Some example usages:

- Creating a LabeledPromise subclass (for better debugging, like RSVP's promises + Ember promise inspector) whose constructor signature is `new LabeledPromise(label, executor)`
- Creating a SaneArray subclass whose constructor signature is `new SaneArray(...elements)` without the special-case for a single argument.
- A more complicated usage in a proposed Element/HTMLElement/MyCustomElement hierarchy [1], to allow custom elements to have custom constructor signatures but still work well with various element-creating parts of the platform.

The LabeledPromise case will, as currently specified, work great. LabeledPromise has a custom `LabeledPromise[Symbol.species](executor)` which basically does `return new this("<derived promise>", executor)`. Then it doesn't have to override `.resolve`, `.reject`, `.all`, or `.then`. However, with your change, `.resolve` will no longer work correctly, even though `.reject` will.

However, the SaneArray case actually will only work for the instance methods, which use ArraySpeciesCreate. In contrast, Array.of and Array.from use Construct(C, <<len>>). That seems like a bug in the spec?

es-discuss mailing list
es-discuss at<mailto:es-discuss at>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list