Killing `Promise.fulfill`

Tab Atkins Jr. jackalmage at gmail.com
Wed Aug 21 19:10:04 PDT 2013


On Wed, Aug 21, 2013 at 5:55 PM, Mark S. Miller <erights at google.com> wrote:
> On Wed, Aug 21, 2013 at 5:33 PM, Tab Atkins Jr. <jackalmage at gmail.com>
> wrote:
>>
>> On Wed, Aug 21, 2013 at 5:12 PM, Mark S. Miller <erights at google.com>
>> wrote:
>> > On Wed, Aug 21, 2013 at 3:44 PM, Tab Atkins Jr. <jackalmage at gmail.com>
>> > wrote:
>> >>
>> >> On Wed, Aug 21, 2013 at 3:36 PM, Domenic Denicola
>> >> <domenic at domenicdenicola.com> wrote:
>> >> > On Aug 21, 2013, at 18:31, "Mark S. Miller" <erights at google.com>
>> >> > wrote:
>> >> >> Good idea. As a coercing function, a natural name is Promise.as(v1).
>> >> >> Also,
>> >> >> as a common coercer, brevity is a virtue.
>> >> >
>> >> > How about just `Promise`, following `String`, `Number`, `RegExp`,
>> >> > etc.?
>> >> >
>> >> > (I tend to agree with Tab that both #a and #b should return a new
>> >> > promise.
>> >> > But we do need an easy coercion function, as Mark emphasizes.)
>> >>
>> >> Yeah, that's the existing coercer idiom.  The other one that's close
>> >> is Array.from().  It still always produces a new object, but that
>> >> doesn't necessarily have to be a property of every class's usage.
>> >>
>> >> But I like just Promise(), sans "new".
>> >
>> >
>> > Good. I like it too, and Allen's latest draft class semantics enables
>> > the
>> > definition of classes that can do this reliably. But is there any way to
>> > reliably polyfill this in ES5? It's not clear. For the std promise API,
>> > given the urgency with which people want to use it *now*, I think this
>> > polyfillability is important.
>>
>> Yes, why wouldn't it be?  The test for promise-ness can be done today,
>> without special browser privilege, and distinguishing between
>> `Promise(foo)` and `new Promise(foo)` is a trivial matter of testing
>> the type of `this` inside the function.  (If it's instanceof Promise,
>> you were called with new.  Otherwise, you weren't.  This isn't 100%,
>> as people can fool you with Promise.call(), but that's not something
>> you need to actually worry about, I think.)
>
>
> This is an example of what I am worried about. Another is
>
>     Object.create(p, {value: Promise}).Promise(....)
>
> where p is a promise.
>
> Perhaps it would help if, when we start to think "people can fool you
> with..." it would help to substitute "an attacker can fool you with...".

An attacker can already fool you with a promise-like, so I don't think
this opens up any additional vectors.  Unless you wanted promise-likes
to return fresh objects too?  That would be a third case, and
potentially confusing for people.  On the other hand, it would mean
that the return value of `Promise(foo)` is always instanceof Promise.

The only way to have a completely reliable type test is to use a
WeakSet to keep track of instances, or store a brand on the object in
a way that only the browser can read/write (such as in the C++
backing, for example).  Do you consider WeakMaps sufficient for
polyfillability?  If so, then we're clear.

~TJ


More information about the es-discuss mailing list