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

