Killing `Promise.fulfill`

Mark S. Miller erights at google.com
Tue Aug 20 09:22:54 PDT 2013


On Tue, Aug 20, 2013 at 9:18 AM, Mark S. Miller <erights at google.com> wrote:

> On Tue, Aug 20, 2013 at 8:32 AM, Tab Atkins Jr. <jackalmage at gmail.com>wrote:
>
>> On Tue, Aug 20, 2013 at 7:08 AM, Mark S. Miller <erights at google.com>
>> wrote:
>> > Hi Anne, Thanks for the reminder. My message of last night fell into
>> that
>> > same old trap (ignoring the storage cost) and that previous reversal of
>> mine
>> > is still mostly correct, However, the missing operation is not .fulfill
>> for
>> > the reasons Domenic correctly explains. It is .accept (possibly named
>> .of)
>> > because it observably differs from .resolve only to .flatMap observers;
>> > whereas the distinction between "pending", "fulfilled" and "rejected" is
>> > observable to .then observers.
>>
>> I have no idea what happened in this thread, because people keep
>> referring to "the earlier X" where by "earlier" they mean "in another
>> unnamed thread, days/weeks ago" rather than just enumerating what
>> they're talking about.  (This kind of thing is acceptable while the
>> other threads are ongoing in parallel; it's not when the threads have
>> been paged out of people's heads.)
>>
>> But in this paragraph, specifically, what are you talking about, Mark?
>>
>
> See <http://lists.w3.org/Archives/Public/www-dom/2013AprJun/0213.html>,
> which is the message Anne links to in the message I'm immediately replying
> to.
>
> But yes, I agree that we've all been using terms like "earlier" too
> loosely, where we should be more explicit about context.
>
>
>
>
>>  What is this "missing operation",
>
>
> .accept
>
>
>
>> who needs it, and why?
>
>
> To answer this precisely, we need good terminology to distinguish two
> levels of abstraction: The distinctions observable to the AP2.flatMap
> programmer and the coarser distinctions observable to the AP2.then
> programmer. Let's start ignoring thenables and considering only
> promises-vs-non-promises. Let's also start by ignoring rejection.
>
> At the AP2.flatMap level,
>   * for a promise p and an arbitrary value v, p may accept v. p is then in
> the "accepted" state.
>   * for a promise p and a promise q, p may adopt q. p is then in the
> "adopting" state.
> Putting these together, we can also say
>   * for a promise p and an arbitrary value v, p is resolved to v if p
> either accepts v or adopts v. p is then in the "resolved" state.
>
> p2 = p1.flatMap(v1 => q2)
>
> means, if p1 is accepted, then v1 will be what it has accepted.
>
> If q2 is a promise, then p2 adopts q2.
>
> p2.flatMap(...) fires as a result of acceptance but not adoption. If q2
> accepts, then p2 likewise accepts and p2.flatMap fires by virtue of this
> acceptance.
>
> At the P2.then level
>


Should be "At the AP2.then level"



>   * for a promise p and a non-promise v, p may be fulfilled with v. p is
> then in the fulfulled state.
>   * for a promise p and a promise q, p may follow q. p is then in the
> following state.
>   * Until a promise p is either fulfilled or rejected, it is pending.
> Putting these together, we can also say
>   * for a promise p and an arbitrary value v, p is resolved to v if either
> p is fulfilled with v or p follows v. p is then in the "resolved" state.
>
> p4 = p3.then(v3 => v4)
>
> means, if p3 is fulfilled, then v3 will be what p3 is fulfilled with.
>
> p4 is resolved to v4. If v4 is a promise, then p4 follows v4. Else p4 is
> fulfilled with v4.
>
> p4.then fires as a result of fulfillment but not following. If p4 follows
> v4 and v4 fulfills, then p4 likewise fulfills and p4.then fires by virtue
> of this fulfillment.
>
> Notice that "resolved" is the same states at each level, even though these
> states are described differently. That is why we can use the same term at
> both levels. Likewise, the concept of "unresolved" is meaningful at both
> levels.
>
>
>
>>
>> From what I understood talking to Domenic, here's what we needed:
>>
>> 1. Promise.resolve() and Promise.reject().  These just take a value
>> and wrap it in a Promise, putting it on the success or failure track.
>>
>
> I'm totally confused by your description of reject, but let's leave it
> aside for now as I have above.
>
> I'm not so much concerned with the static .resolve method, since the extra
> storage cost for the static method is negligible. However, what does
> aResolve.resolve do? If it causes its promise to accept, this must be
> observably different to .flatMap observers than if it causes its promise to
> adopt. This difference is not observable to .then observers, which is why
> I've accidentally missed this issue twice now. But since an implementation
> cannot know ahead of time whether there might be .flatMap observers, using
> .accept for .resolve would impose prohibitive storage costs on .then
> oriented patterns. See the message Anne linked to.
>
>
>>
>> 2. Promise#then() and Promise#flatMap().  flatMap waits for pending
>> promises to become resolved or rejected,
>
>
> If p adopts q and q is unresolved, then p is resolved but p.flatMap does
> not fire.
>
>
>
>> and calls its callbacks
>> accordingly; then() waits for pending or resolved promises to become
>> fulfilled or rejected, and calls its callbacks accordingly.
>>
>> 3. The resolved value of a promise (what's passed to the success
>> callback of flatMap()) is simply the value in the promise.
>
>
> True for acceptance, not for adoption.
>
>
>
>>  The
>> fulfilled value of a promise (what's passed to the success callback of
>> then()) depends on what's inside the promise: if it's a plain value,
>> that's the fulfilled value; if it's a promise, its that promise's
>> fulfilled value.
>>
>> Do you think we need anything else?  If so, why, and for what purpose?
>>
>
> Only to avoid the prohibitive storage cost of using .accept to do the job
> of .resolve. Storage aside, there is no semantic need to distinguish these
> two.
>
>
>
>>
>> (Note that if anyone thinks we need something that eagerly flattens a
>> promise, rather than flattening happening implicitly via the
>> definition of "fulfilled value" for then(), realize that this eager
>> flattening operation is hostile to lazy promises.  While this might be
>> *useful* in some cases, it's probably not something we need or want in
>> the core language, or if we do, it should be given an appropriately
>> descriptive name, rather than yet another synonym for "accept".)
>>
>
> I agree that we do not need eager flattening.
>
>
>
>>
>> ~TJ
>>
>
>
>
> --
>     Cheers,
>     --MarkM
>



-- 
    Cheers,
    --MarkM
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130820/fa9c8117/attachment.html>


More information about the es-discuss mailing list