What Are We Arguing About? (was: Re: A Challenge Problem for Promise Designers)

# Mark Miller (12 years ago)

On Fri, Apr 26, 2013 at 8:18 AM, Andreas Rossberg <rossberg at google.com> wrote: [...]

Let me note that this is not the fundamental controversy (not for me, anyway). The fundamental controversy is whether there should be any irregularity at all, as is unavoidably introduced by implicit flattening. The problem you describe just makes the negative effect of that irregularity worse.

/Andreas

First, my apologies to all for replying after having only skimmed this morning's messages. My sense is that indeed there are several different arguments going on simultaneously that are often difficult to untangle.

I posed my challenge problem primarily as a response to Andreas' position. Andreas, please rewrite the very small example in the linked-to paper (Also at code.google.com/p/es-lab/source/browse/trunk/src/ses/contract) in terms of the uniform non-flattening semantics you desire.

Second, I intend it to show why default flattening is desirable. By itself the challenge problem does not argue for or against

  1. the possibility of promises-for-promises, as Alex correctly observes, so long as this is clearly marked as "only for experts"
  2. the unwrapping of thenables
  3. assimilation -- the recursive unwrapping of thenables.
  4. whether promises recognize their own bretheren as promises, or just treat them all as thenables
  5. whether some continue to alienate the JS promise community by continued use of the term "future"
  6. what kind of extension mechanism (e.g., subclassing or makeRemote) a promise system should provide
  7. under what organization should promises be standardized

So that we can refer to it in the same namespace, let's call the controversy about default flattening #0

Obviously, the answer to #4 determines whether there is a meaningful difference between flattening and assimilation.

These are each important distinctions. My position is that default flattening is a must. That the beauty of flattening is an important principle, but assimilation is an expedient but necessary hack. The need for flattening is eternal, as the joy of flattening has survived through several languages and the pain of non-flattening has been shared experience across many languages. However, the need for assimilation is history dependent. If there is another plausible-enough path to adoption and widespread use of promises that does not require assimilation, I would be very happy. But I have not found any of the alternatives posted so far to be plausible enough.

Regarding #5 and #7, can we put these to bed already? AFAICT, the clear consensus of these lists is that TC39 will be proceeding with promises. The continued occasional use of "future" terminology seems to be only territory-marking behavior, and divides the community with an "us vs them" mentality.

I agree with Alex that the main technical disagreement with DOMFutures is #1. My example shows the utility and beauty of flattening. Could you, or anyone who argues for a "fulfill" (aka "accept") operation, show an example of the utility of non-flattened promises? (And please keep this question distinct from questions about thenables.)

# David Bruant (12 years ago)

Le 26/04/2013 17:58, Mark Miller a écrit :

However, the need for assimilation is history dependent. If there is another plausible-enough path to adoption and widespread use of promises that does not require assimilation, I would be very happy. But I have not found any of the alternatives posted so far to be plausible enough.

Let's try. It's pretty much a rehash of what I've proposed already, but I'm trying here to demonstrate that it is plausible.

Let's first divide the world of existing code using promises (one or several promise libraries independently) in to categories: (1) unmaintained code (sitting on a website somewhere, nobody is modifying the code) (2) maintained code (deployed in production too, some people do touch the code)

Before the introduction of platform promises, both code works. After the inclusion of platform promises, (1), oblivious of the fact that anything has changed still works. After the inclusion of platform promises, only those in (2) will be of concern.

One idea would be for application using non-platform promises to wrap platform promises into something they understand. Developers will need the discipline to mainly use non-platform promises (as platform promises wouldn't recognize any other object as a promise)

Where should this wrapping occur? Each library can add a check+convert to all surface API. It doesn't sound that hard (library authors can jump in to say I'm crazy here).

It imposes all existing project to upgrade all their promise libraries to a version that wrap natives if they want to use platform promises too.

Hopefully, that should work until an ecosystem (or several) built on top of platform promises emerge and new projects should be built on top of this new ecosystem.

So in the end, it takes:

  1. new version of libraries to auto-wrap platform promises (preferably happening in a non-API-breaking way)
  2. existing projects upgrade their promise libraries
  3. existing projects stick to promises library and don't use platform features (DOMFuture statics)
  4. a platform promise ecosystem emerges
  5. new projects only use the new platform ecosystem (or respect 3)

How plausible does this sound?

# Tab Atkins Jr. (12 years ago)

On Fri, Apr 26, 2013 at 8:58 AM, Mark Miller <erights at gmail.com> wrote:

On Fri, Apr 26, 2013 at 8:18 AM, Andreas Rossberg <rossberg at google.com> wrote:

Let me note that this is not the fundamental controversy (not for me, anyway). The fundamental controversy is whether there should be any irregularity at all, as is unavoidably introduced by implicit flattening. The problem you describe just makes the negative effect of that irregularity worse.

First, my apologies to all for replying after having only skimmed this morning's messages. My sense is that indeed there are several different arguments going on simultaneously that are often difficult to untangle.

I posed my challenge problem primarily as a response to Andreas' position. Andreas, please rewrite the very small example in the linked-to paper (Also at code.google.com/p/es-lab/source/browse/trunk/src/ses/contract) in terms of the uniform non-flattening semantics you desire.

Are you referring to this example, from your OP in the earlier "Challenge for Promise Designers" thread?

deposit: (amount, srcP) =>
  Q(srcP).then(src => {
    Nat(balance + amount);
    m.get(src)(Nat(amount));
    balance += amount;
})

If so, then the effect of this code is to allow srcP to be either a plain value or a promise for a value, and the deposit() function should work equally well with either. (As opposed to always expecting a plain value, which requires the call sites to wait on the resolution of their promises, or always expecting a promise, which requires the call sites to wrap their plain values.)

This can be trivially rewritten to the same effect with Futures:

deposit: (amount, srcP) =>
  Future.resolve(srcP).then(src => {
    Nat(balance + amount);
    m.get(src)(Nat(amount));
    balance += amount;
})

Future.resolve() is the future-coercion operator: if you pass it a future, it returns a new (but equivalent) future; if you pass it a non-future, it returns a future for that value. Using it allows you to write functions that can take either plain values or futures for values.

Second, I intend it to show why default flattening is desirable. By itself the challenge problem does not argue for or against

  1. the possibility of promises-for-promises, as Alex correctly observes, so long as this is clearly marked as "only for experts"
  2. the unwrapping of thenables
  3. assimilation -- the recursive unwrapping of thenables.
  4. whether promises recognize their own bretheren as promises, or just treat them all as thenables
  5. whether some continue to alienate the JS promise community by continued use of the term "future"
  6. what kind of extension mechanism (e.g., subclassing or makeRemote) a promise system should provide
  7. under what organization should promises be standardized

So that we can refer to it in the same namespace, let's call the controversy about default flattening #0

Obviously, the answer to #4 determines whether there is a meaningful difference between flattening and assimilation.

These are each important distinctions. My position is that default flattening is a must. That the beauty of flattening is an important principle, but assimilation is an expedient but necessary hack. The need for flattening is eternal, as the joy of flattening has survived through several languages and the pain of non-flattening has been shared experience across many languages. However, the need for assimilation is history dependent. If there is another plausible-enough path to adoption and widespread use of promises that does not require assimilation, I would be very happy. But I have not found any of the alternatives posted so far to be plausible enough.

I agree that assimilation might be required to be recursive, to be maximally useful. I've got no problem with that - assimilation is an interface with the outside world, is often magical in these kinds of situations, and is a separate function from what "normal" promises will use.

I have not yet seen any arguments for flattening that aren't about assimilation, weird language constructs that aren't applicable to JS, or authoring errors. My response to David Bruant in lists.w3.org/Archives/Public/public-script-coord/2013AprJun/0239.html covers this objection in slightly more detail.

If you believe that flattening really is necessary, or even beautiful, I don't think you've demonstrated it yet (or if you have, I've misunderstood your examples, and would appreciate correction).

Regarding #5 and #7, can we put these to bed already? AFAICT, the clear consensus of these lists is that TC39 will be proceeding with promises. The continued occasional use of "future" terminology seems to be only territory-marking behavior, and divides the community with an "us vs them" mentality.

Actually, I keep using the term Future because that's the current name for the standardized version of promises, and it provides an easy way to distinguish between default flattening and not - "promise" refers to Promises/A+, which has default flattening, while "future" refers to DOM Futures, which flattens monadically.

Anyone who reads territoriality into this is reading too much. Don't worry about it. These things will get defined somewhere, under some name, and we'll decide that all later.

I agree with Alex that the main technical disagreement with DOMFutures is #1. My example shows the utility and beauty of flattening. Could you, or anyone who argues for a "fulfill" (aka "accept") operation, show an example of the utility of non-flattened promises? (And please keep this question distinct from questions about thenables.)

As far as I can tell, your example does not show any flattening at all. I responded as such in your earlier thread, and asked you to correct me if I was making wrong assumptions at any point, but you appeared to have jumped threads (I don't blame you - the other one exploded over night/this morning). So, I'll pose the question to you again: am I wrong, or does your example have nothing to do with flattening?

~TJ

# Domenic Denicola (12 years ago)

I think this is a really good description of the problems and possible solutions. Unfortunately, I think you underestimate the problems.

Where should this wrapping occur? Each library can add a check+convert to all surface API. It doesn't sound that hard (library authors can jump in to say I'm crazy here).

It's not fun, and it's pretty hard. We do this daily with Node.js libraries. Creating duplicates of existing APIs, and keeping them in sync, sucks. I would go almost as far as to say that this results in people thinking that the W3C has invented yet another sucky callback API that they can't use in a composable way with their existing code. Hooray, back where we started...

Hopefully, that should work until an ecosystem (or several) built on top of platform promises emerge and new projects should be built on top of this new ecosystem.

And, because of how the platform forced users to wrap platform promises, this seems unlikely. Why would they dedicate resources to build on top of a library that didn't feel fit to give them the time of day and integrate with them? Better to just keep using the ecosystem they already have, which doesn't cause such problems and doesn't need to be forked and rewritten for an outlier.

We are no stranger to the W3C producing crappy APIs that we bury under wrapping layers as soon as possible and never see again (see: jQuery). It would be a shame if promises in the DOM turned out to be another one of those.

# Juan Ignacio Dopazo (12 years ago)

2013/4/26 Mark Miller <erights at gmail.com>

On Fri, Apr 26, 2013 at 8:18 AM, Andreas Rossberg <rossberg at google.com> wrote: [...]

the term "future"

What are the chances of the WHATWG renaming the spec to DOMPromise?

Juan

# Tab Atkins Jr. (12 years ago)

On Fri, Apr 26, 2013 at 12:17 PM, Juan Ignacio Dopazo <dopazo.juan at gmail.com> wrote:

2013/4/26 Mark Miller <erights at gmail.com>

On Fri, Apr 26, 2013 at 8:18 AM, Andreas Rossberg <rossberg at google.com> wrote: [...] the term "future"

What are the chances of the WHATWG renaming the spec to DOMPromise?

Let's please, everyone, ignore the naming issue. It's completely irrelevant to anything being discussed right now, and can be resolved at a future time. (Ha!) Bringing it up now does nothing but add noise and heat to the discussions unnecessarily.

# David Bruant (12 years ago)

Le 26/04/2013 20:39, Domenic Denicola a écrit :

I think this is a really good description of the problems and possible solutions. Unfortunately, I think you underestimate the problems.

Where should this wrapping occur? Each library can add a check+convert to all surface API. It doesn't sound that hard (library authors can jump in to say I'm crazy here). It's not fun, and it's pretty hard. We do this daily with Node.js libraries. Creating duplicates of existing APIs, and keeping them in sync, sucks.

This is a different problem. You're keeping in sync promises with an ecosystem based on callbacks, where there is a main convention (callback as last argument accepting (err, val)) with a lot of exceptions. To wrap platform promises, you will need only one function. Platform promises come in one shape, no exception. That's much much less work than what you're doing with Node.js.

Note that if you want to turn existing APIs (xhr, geoloc, etc.) to promise-oriented APIs, additional work has to be done regardless of compat with other libraries.

I would go almost as far as to say that this results in people thinking that the W3C has invented yet another sucky callback API that they can't use in a composable way with their existing code. Hooray, back where we started...

Where we diverge in opinion is that I believe it's not the platform role to be compatible with existing libraries. That didn't happen with jQuery which is thousands of times more used than promise libraries for instance (however good ideas from jQuery were later added to the platform like querySelectorAll, forEach, CSS animation, etc.) Promise libraries have led a similar battle and I'm happy to see that we're discussing the inclusion of promises to the platform (in that sense, we're much much further than where we started). I however don't see why the platform should be compatible with existing code. Historically, when a new API was emerging to implement what authors had been doing, the platform API wasn't compatible with existing code and everyone survived. What is so important about promises that would be enough of an incentive for the platform to be compatible with existing code? Are the costs on the platform side worth it for cases where there is no need to be compatible with existing library (which I believe will be the majority and will increase as time passes since not everyone will want more than what the default API provides)? People who use existing promise libraries are not the only people concerned by the introduction of platform promises.

I demonstrated that the cost for existing libraries is manageable (one wrapping function to be called at the entrance of surface API, some discipline). That was enough for other libraries when other features were integrated to the platform.

Hopefully, that should work until an ecosystem (or several) built on top of platform promises emerge and new projects should be built on top of this new ecosystem. And, because of how the platform forced users to wrap platform promises, this seems unlikely. Why would they dedicate resources to build on top of a library that didn't feel fit to give them the time of day and integrate with them? Better to just keep using the ecosystem they already have, which doesn't cause such problems and doesn't need to be forked and rewritten for an outlier.

Some people will start using platform promises without existing libraries. Whether they'll want to add existing full-features libraries isn't sure yet. Whether they'll want to start something smaller than the existing promise libraries may happen.

We are no stranger to the W3C producing crappy APIs that we bury under wrapping layers as soon as possible and never see again (see: jQuery). It would be a shame if promises in the DOM turned out to be another one of those.

More and more, people are advocating to stop using jQuery (and use the crappy APIs) when targeting modern browsers, because cases where jQuery was necessary are now often taken care of by the platform. Additionally, work on DOM4 is bringing better APIs (thinking of .remove() and .on() for example). Lot of work by Anne and Ms2ger here. Things are improving slowly on the platform API side.

# Andreas Rossberg (12 years ago)

On 26 April 2013 17:58, Mark Miller <erights at gmail.com> wrote:

I posed my challenge problem primarily as a response to Andreas' position. Andreas, please rewrite the very small example in the linked-to paper (Also at code.google.com/p/es-lab/source/browse/trunk/src/ses/contract) in terms of the uniform non-flattening semantics you desire.

Hi Mark,

sorry for not having followed up on that, but for one, too much of my bandwidth was eaten up by the modules thread for a sufficiently detailed reply, and secondly, I felt that Tab was already doing a terrific job of answering it (and generally unraveling most of the misunderstandings in this thread). Also, it already was weekend over here. :)

So what Tab said, in reply to your challenge and elsewhere.