Le 10 mai 2013 à 14:55, Mark S. Miller <[email protected]> a écrit :

> [+es-discuss]
> 
> I didn't realize that I composed this in reply to a message only on 
> public-script-coord. Further discussion should occur only on es-discuss. 
> Sorry for the confusion.
> 
> 
> On Fri, May 10, 2013 at 5:52 AM, Mark S. Miller <[email protected]> wrote:
> I think the key exchange in these threads was
> 
> On Fri, May 3, 2013 at 4:17 PM, Jonas Sicking <[email protected]> wrote:
> [...]
> I.e. permitting nested promises creates a more complex model and with
> that you always get more confusion and more questions.
> 
>  On Sat, May 4, 2013 at 1:48 AM, Claus Reinke <[email protected]> wrote:
> [...]
> From the perspective of a-promise-is-just-like-other-wrapper-classes,
> auto-flattening promises creates a more complex model
> 
> 
> Together with each of their explanations about what they meant. They are both 
> right. Lifting and auto-lifting do not mix. Q Promises give us autolifting 
> with no lifting. Monadic promises would give us lifting but no autolifting. 
> Having both in one system creates a mess which will lead programmers into the 
> particular pattern of bugs Jonas warns about in his message.
> 
> For clarity I define the following APIs so I can define the three 
> architectural choices in terms of the subset of these APIs they contain. 
> Obviously, I do not intend to start a bikeshed yet on the particular names 
> chosen for these operations. Let's stay focused on semantics, not terminology.
> 
> An upper case type variable, e.g. T, is fully parametric. It may be a promise 
> or non-promise.
> A lower case type variable, e.g. t, is constrained to be a non-promise. If 
> you wish to think in conventional type terms, consider Any the top type 
> immediately split into Promise and non-promise. Thus type parameter t is 
> implicitly constrained to be a subtype of non-promise. 
> 
> 
> 
> 
> Ref<T> is the union type of T and Promise<T>.
> 
> Q.fulfill(T) -> Promise<T> // the unconditional lift operator
> 
> Q(Ref<t>) -> Promise<t> // the autolift operator
> 
> p.map: Promise<T> -> (T -> U) -> Promise<U>
> 
> p.flatMap: Promise<T> -> (T -> Promise<U>) -> Promise<U>
> // If the onSuccess function returns a non-promise, this would throw an 
> Error, 
> // so this type description remains accurate for the cases which succeed.
> 
> p.then: Promise<T> -> (T -> Ref<u>) -> Promise<u>
> // Ignoring the onFailure callback
> 
> 
> 
> * A Monadic promise system would have Q.fulfill, p.map, and p.flatMap.
> 
> * A Q-like promise system would have Q, and p.then
> 
> * The dominant non-Q-like proposal being debated in these threads has 
> Q.fulfill, Q, and p.then. 
> 
> 

Hello,

With this explanation, from my perspective (as someone who has never used 
promises, but rejoices in advance to use them), the Q-like model of promise 
seems far superior to me:

* lifting (for non-promises) + no-op (for promises) is advantageously replaced 
by one method, autolifting (working with both);
* `flatMap` (for promises) + `map` (for non-promises) is advantageously 
replaced by one method, `then` (working with both);

It follows that:
* it is impossible to have a promise for a promise, reducing the probability of 
bugs;
* it makes it easier to write generic algorithms that work for both 
non-promises and promises;
* in many situations, there is no need to ask oneself if one should provide a 
promise or a non-promise, reducing the burden of thinking to programmers and 
therefore the probability of bugs.

Not wanting to ask oneself «Should I provide a promise or a value?» is not 
sloppiness, but it is because promises are just uninteresting wrappers. I never 
ask myself: «Should I provide a string or a String object to the `substring` 
method?», because it doesn't matter, and the String object is just an 
uninteresting wrapper. And to push the comparison further: it is dubious, and 
hopefully impossible, to wrap a String object in another String object, just 
like it is dubious to have a promise for a promise.


> 
> 
> <snip>
> 
> The main failure mode of standards bodies is to resolve a conflict by adding 
> the union of the advocated features. Here, this works even worse than it 
> usually does. The coherence of lifting depends on the absence of autolifting, 
> and vice versa. We need to make a choice.

Indeed, the advantages I have mentioned vanished if we add unconditional 
lifting to autolifting + `then`, because its bare use forces the programmer to 
think what type of object he should provide (a promise or a non-promise) in 
some situations. If you allow me to do a somewhat shaky comparison, the 
usefulness of ASI is greatly reduced by the few situations where ASI does not 
work; therefore most style guides recommend to not use ASI at all.


—Claude


> 
> 
> -- 
>     Cheers,
>     --MarkM
> 
> 

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to