Re: A Challenge Problem for Promise Designers

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

> On 26 April 2013 16:25, Dean Landolt <dean@deanlandolt.com> wrote:
> > The fundamental controversy, as Juan just noted, is how to precisely
> > identify a promise in order to do either of these two things. This
> problem
> > isn't quite so clean cut, but it's much more important to solve. I've
> been
> > trying to bring some attention to it over the last few days -- I hope
> it's
> > clear that a `then` method is not enough to identify a promise language
> > construct -- this will subtly break existing code (e.g. casperjs).
>
> 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.
>


It may be a little late (I'm just catching up on these promise megathreads)
but I was suggesting that the irregularity posed by flattening is only a
distraction. AFAICT you're concern with flattening is actually in regard to
resolution semantics, right? Otherwise it's unobservable whether you have a
Promise<value> or a Promise<Promise<value>>. I'm trying to argue that given
a reliable branding a one-step resolver is easy and sensible to define (no
flattening), and a recursive resolver is an obvious extension. Almost
everyone would use the latter, but I completely agree that the former is
necessary too. No irregularities, everybody wins.

I don't think I've been able to properly communicate the gravity of the
branding issue. I'll try code:


  getAFuture()
    .then(function(x) {
      return require('casper').create();
    });


Assuming you know that factory returns a Casper instance, you would
probably expect a Promise<Casper> value, right? But Casper instances have
`then` methods, so it'll quack like a promise to the Promises/A+
assimilation algorithm, so what gets returned will be a Promise<undefined>
value. You may luck out and notice some non-sensical behavior, but it's
very possible this code could *almost* work just fine -- right until it
doesn't. It's more than just a debug hazard -- this kind of code could
easily slip into production even with awesome test coverage.

Casper's just a convenient example -- this problem applies to all
"thenables" that aren't Promises/A+ promises. What's worse, the semantics
of the word `then` imply that many of these thenable objects will probably
*almost* work in the same way as the example above.


To my mind the question of flattening sorts itself out as soon as you
define a means to reliably identify a promise. But it could also be
sidestepped completely, which I believe is the option Dave Herman favored
at one point...

It's been a few years but I recall an exchange we had where he took the
position that there shouldn't even be a method to test whether a value is a
promise -- IIRC he was arguing that any `value | Promise<value>`
functionality was unnecessary, and even hazardous. I was never clear on
exactly how this could be made to work, especially in interoperable
libraries, but as a language construct I suppose it's feasible. I'm curious
to hear where Dave stands now -- he eventually built support for thenables
into task.js (which I think was what sparked this exchange) but that could
have been out of convenience. Of course, with this approach I can't imagine
how promises could possibly be made nestable with one-step resolution (what
people seem to be calling "monadic" now?).

Received on Saturday, 27 April 2013 21:22:39 UTC