Andreas Rossberg (2014-01-28T23:27:55.000Z)
On 28 January 2014 21:21, Quildreen Motta <quildreen at gmail.com> wrote:
> So, if I understand correctly, it basically boils down to:
>
> Promise.resolve :: a → Promise(a)
>
> Promise.cast :: a → Promise(a)
> Promise.cast :: Promise(a) → Promise(a)
>
> But right now we'll only get `.then`, so transformations with nested
> promises will flatMap automatically:
>
> Promise.then :: (Promise(a)) => ((a → MaybePromise(b), (a → MaybePromise(b))
> Promise.then :: (Promise(Promise(a))) => ((a → MaybePromise(b), (a →
> MaybePromise(b))

This type is not really accurate. Due to recursive unwrapping, `then'
has no type you could express in any reasonable type system -- the
argument type can be an arbitrary tower of nested promises (and the
maximum one for each use). As you note below, this makes the operation
inherently non-parametric. (Which is why I still hold up that
recursive unwrapping is a bad idea, especially as the core primitive.)

> But later, once `flatMap` is introduced, you'll be able to deal with nested
> promises without breaking parametricity:
>
> Promise.flatMap :: (Promise(a)) => (a → Promise(b))
>
> If that's correct, I don't see any use cases for Promise.resolve right now,
> unless a library where to provide a corresponding unspecified `flatMap`
> implementation.

The V8 implementation provides it under the name `chain', with the
obvious semantics.

/Andreas


> On 28 January 2014 18:07, Paolo Amadini <paolo.02.prg at amadzone.org> wrote:
>>
>> [Replying here since I'm not sure about how to move the discussion to
>> the issue tracker without losing the context of Mark's observation.]
>>
>> On 28/01/2014 20.28, Mark S. Miller wrote:
>> > For people concerned only about the .then level of abstraction, I see
>> > little reason to ever use Promise.resolve rather than Promise.cast, and
>> > much reason to prefer Promise.cast. But fwiw we did agree to express the
>> > difference now, to be perceived by future and experimental uses of
>> > .flatMap in the future.
>>
>> I don't have a background on the .flatMap level of abstraction. In the
>> following scenario, will users of getMyPromise() have a different
>> behavior with .flatMap if the library code used "cast" rather than
>> "resolve"? If so, this can definitely lead to confusion when .flatMap
>> is introduced in the future since the callers cannot be sure about
>> what the library did internally, assuming the library authors didn't
>> intentionally choose one or the other.
>>
>> ```js
>> // ------ MyLibrary.js
>>
>> function getMyPromise() {
>>   var a = condition ? getMyOtherPromise() : "value2";
>>   return Promise.resolve(a);
>> }
>>
>> function getMyOtherPromise() {
>>   return Promise.resolve("value1");
>> }
>> ```
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>
>
>
>
> --
> --
> Quildreen "(Soreλ\a)" Motta  (http://robotlolita.github.io/)
> — JavaScript Alchemist / Minimalist Designer / PLT hobbyist —
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
domenic at domenicdenicola.com (2014-02-04T16:10:56.607Z)
On 28 January 2014 21:21, Quildreen Motta <quildreen at gmail.com> wrote:

> ```
> Promise.then :: (Promise(a)) => ((a → MaybePromise(b), (a → MaybePromise(b))
> Promise.then :: (Promise(Promise(a))) => ((a → MaybePromise(b), (a → MaybePromise(b))
> ```

This type is not really accurate. Due to recursive unwrapping, `then'
has no type you could express in any reasonable type system -- the
argument type can be an arbitrary tower of nested promises (and the
maximum one for each use). As you note below, this makes the operation
inherently non-parametric. (Which is why I still hold up that
recursive unwrapping is a bad idea, especially as the core primitive.)

> But later, once `flatMap` is introduced, you'll be able to deal with nested
> promises without breaking parametricity:
>
> ```
> Promise.flatMap :: (Promise(a)) => (a → Promise(b))
> ```
>
> If that's correct, I don't see any use cases for Promise.resolve right now,
> unless a library where to provide a corresponding unspecified `flatMap`
> implementation.

The V8 implementation provides it under the name `chain', with the
obvious semantics.