On Wed, Aug 21, 2013 at 5:33 PM, Tab Atkins Jr. <[email protected]>wrote:
> On Wed, Aug 21, 2013 at 5:12 PM, Mark S. Miller <[email protected]> > wrote: > > On Wed, Aug 21, 2013 at 3:44 PM, Tab Atkins Jr. <[email protected]> > > wrote: > >> > >> On Wed, Aug 21, 2013 at 3:36 PM, Domenic Denicola > >> <[email protected]> wrote: > >> > On Aug 21, 2013, at 18:31, "Mark S. Miller" <[email protected]> > 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...". > > >> There's no > >> behavioral difference between resolving and accepting for .then(), so > >> we don't need it there, and you already need to be careful that your > >> value is wrapped in a promise for .flatMap() callbacks, so requiring > >> the same for the resolver function when those are the semantics you > >> want is fine with me. > > > > I did not understand this reasoning even though I like its conclusion. > Could > > you expand on this, perhaps with examples? Thanks. > > Okay. > > For .then(), you can't tell the difference between adopting and just > fulfilling with a promise, because both will wait for the inner > promise to fulfill before the outer promise fulfills. So obviously > you don't need a resolver function for "just wrap it" if you're using > .then(). > > For .flatMap(), there's a clear difference between the two. However, > we should probably engineer toward making things similar for the > resolver and a .flatMap() callback. In a callback, if you want to > return a nested promise, you have to first wrap it in a throwaway > promise (which will then get adopted away). That is: > > p1.flatMap(x=>p2).flatMap(print) // prints whatever value p2 resolves to > p1.flatMap(x=>Promise.of(p2)).flatMap(print) // prints p2 itself, not > its resolved value > > Similarly, if you limit yourself to just the resolve/reject resolver > functions: > > new Promise(r=>r.resolve(p2)).flatMap(print) // prints whatever value > p2 resolves to > new Promise(r=>r.resolve(Promise.of(p2))).flatMap(print) // prints p2 > itself, not its resolved value > Aha. Good I get it. Yes, I enthusiastically agree. > > On the other hand, if you allow the accept resolver function: > > new Promise(r=>r.accept(pw)).flatMap(print) // prints p2 itself, not > its resolved value > > I'm fine with requiring the bit of extra work that's needed without > accept, due to the symmetry - Resolver#resolve is exactly identical to > returning from a callback, and Resolver#reject is exactly identical to > throwing from a callback, but there's no way to duplicate > Resolver#accept from a callback, and thus it's not clear that this > functionality is actually needed. > Yes. > > >> We'll still need the class static for it, just not the resolver > >> function. I propose we quit with the synonyms, and use Promise.of() > >> like I (and others) proposed a long time ago. ^_^ > > > > I do not love this but I do not object. +0.8 ;). > > Cool. That means we get a decent naming precedent for the monad ops, > and consistency with Array.of (which also happens to be a monadic > lifter, if you limit yourself to calling it with only a single > argument). > I agree that this naming analogy is a good thing. I raise my approval magnitude to +1 ;). > > ~TJ > -- Cheers, --MarkM
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

