- From: Mark Miller <erights@gmail.com>
- Date: Sat, 27 Apr 2013 09:48:09 -0700
- To: "Tab Atkins Jr." <jackalmage@gmail.com>
- Cc: Domenic Denicola <domenic@domenicdenicola.com>, David Bruant <bruant.d@gmail.com>, "Mark S. Miller" <erights@google.com>, "public-script-coord@w3.org" <public-script-coord@w3.org>, Dean Tribble <tribble@e-dean.com>, es-discuss <es-discuss@mozilla.org>
- Message-ID: <CAK5yZYhCOsSMHks7TaAaqoxvUo79VZ3y6JKjHABvMNpKwEnGPQ@mail.gmail.com>
Cool. I think we (at least you and I) have agreement on default flattening (#0). FWIW, the reason I'm surprised that you're calling this monadic is the need for the dynamic test on 'as long as "b" isn't a Promise'. In other words, the signature of .then (including the receiver and excluding the errback) is overloaded as promise<a> -> (a -> promise<b>) -> promise<b> or promise<a> -> (a -> b) -> promise<b> // when b is not itself a promise type My impression is that each of these overloads by itself is a different monad operation and that testing the condition in the comment violates parametricity. If these do correspond to two different monad operations, then different laws cover each. A similar analysis applies to Q(x) (aka Future.resolve(x)). In any case, no matter. We agree (assimilation aside) that this is how .then and Q should behave. Wonderful! On Sat, Apr 27, 2013 at 9:28 AM, Tab Atkins Jr. <jackalmage@gmail.com>wrote: > On Sat, Apr 27, 2013 at 7:38 AM, Mark Miller <erights@gmail.com> wrote: > > On Fri, Apr 26, 2013 at 1:51 PM, Tab Atkins Jr. <jackalmage@gmail.com> > > wrote: > >> On Fri, Apr 26, 2013 at 1:45 PM, Domenic Denicola > >> <domenic@domenicdenicola.com> wrote: > >> > From: Tab Atkins Jr. [jackalmage@gmail.com] > >> >> Shorter me: this is why I keep asking people who want flattening to > >> >> actually provide an example of where flattening is useful, that > isn't (a) > >> >> assimilation, (b) a result of weird language semantics from some > non-JS > >> >> language, or (c) an authoring error. > >> > > >> > Since (multi-level) flattening only occurs for assimilation (per > >> > Promises/A+ 1.1), it appears we have been talking past each other. All > >> > examples of multi-level flattening will necessarily be examples of > >> > assimilation. > >> > >> In that case, HUZZAH! We've solved the problem! > > > > > > We may have. > > > > When I argue for default flattening (#0 in my "What Are We Arguing > About") > > and you argue against, you claim default flattening is not monadic, > which I > > agree with. But then you go on to explain as "monadic" a semantics that > > seems like default flattening to me. I am curious if you could define > what > > you mean by "monadic". I don't much care if we call a promise system > > "monadic" or not, but let's not let a disagreement on this term obscure a > > possible agreement on what promises should do. > > Hmm, that's strange. I just mean "following the monad laws". In > other words, Promises are monads, with .then as the monadic operation, > taking a function of type "a -> Promise<b>", and resulting in a new > Promise. (For convenience, .then() is also the functor operation, > allowing its function to be of type "a -> b", as long as "b" isn't a > Promise. But that doesn't harm the monad-ness, as long as you follow > the laws.) Future.accept (or its equivalent in a final Promise spec) > is the monadic lift operation. > > We don't expose it explicitly (though we could), but the monadic > "join" operation takes a Promise<Promise<a>>, and returns a new > promise that waits for both the inner and outer to accept, then > accepts with the inner's state. If either rejects, the output promise > rejects with the same reason. > > Did you think I meant something else? If so, what? And, do you think > I've made a mistake in describing the monadic properties of promises? > If so, what? > > > As I made clear in my "What Are We Arguing About" email, I want to > separate > > the argument about default flattening (#0) from the argument about > whether > > promises-for-promises are possible (#1), and from arguments about > thenables > > and assimilation (#2,#3,#4). > > > > AFAICT, leaving aside operations that would explicitly create > > promises-for-promises, i.e., "fulfill" (aka "accept"), I don't see how > it is > > possible to create promises-for-promises with the remaining operations > you > > and I seem to agree on: Q(x) (aka "Future.resolve(x)"), "then", > "resolve", > > "reject". If promise-for-promises cannot be made in the first place, > then no > > recursive unwrapping is required to take them apart. Specifically, > > assimilation aside and API details aside, what about Q do you disagree > with, > > if anything? > > Correct - if you leave out the only promise constructor that can > actually make promises-for-promises, you can't make > promises-for-promises. ^_^ Thus, recursive unwrapping, outside of > the assimilation use-case, isn't useful, as it's very hard to nest > promises unless you're doing it on purpose. (And if you are doing it > on purpose, it's potentially useful to have it act monadic.) > > > If we can narrow our remaining disagreements down to #1..#7, that would > be > > great progress. Yes, #1..#7 will still be a lot of work, but great > progress > > nonetheless. And I will leave to you and other to fight about what is and > > isn't called "monadic" ;). > > No fights necessary, luckily - the monad laws are completely trivial, > and it's easy to prove something does or doesn't obey them. > > ~TJ > -- Text by me above is hereby placed in the public domain Cheers, --MarkM
Received on Saturday, 27 April 2013 16:48:36 UTC