A Challenge Problem for Promise Designers (was: Re: Futures)
rossberg at google.com
Fri Apr 26 04:24:23 PDT 2013
On 26 April 2013 12:19, David Bruant <bruant.d at gmail.com> wrote:
>> In particular, irregularity and exceptions become a pain
>> when you start building abstractions, or plug together abstractions.
>> In other words, regularity is a prerequisite for what some people
>> (including me) like to call "compositionality".
>> Flattening for futures/promises is irregular because it means that
>> certain behaviour reliably exists in all cases _except_ when the input
>> is itself a future/promise. This may not seem like a big deal if you
>> use them directly. But now imagine somebody built a bigger generic
>> abstraction that uses futures/promises only internally. You find that
>> abstraction useful, and for whatever reason, need to funnel in a value
>> that happens to be a future.
> This last sentence and especially the ambiguous "for whatever reason" is the
> heart of the debate I believe. The idea expressed by Kevin Smith of promises
> as featureless values is that there should be no reason for you to funnel a
> value that happens to be a promise unless it's expected to be a promise and
> not a non-promise value.
> I have read somewhere (I can't remember where, hopefully MarkM will confirm
> or say if I imagined it) that in E, if a variable contains a promise and
> this promise is resolved, then the variable unwraps its value and
> referencing to the variable suddenly means referencing to the value.
> Promises are so deeply embedded in the language (syntax included) that this
> unwrapping is seamless.
> If I didn't imagine this, it'd be interesting if MarkM could expand on that
> as it seems to imply that promises shouldn't be values but lower-level than
> Even if he confirms, it probably won't be possible to have something that
I'm not sure if your description of E is accurate -- I'd find that
surprising. It _is_ a perfectly sensible design to have transparent
futures that you can just use in place of the value they eventually
get resolved to (let's call that value their 'content'). In fact, that
is how futures/promises where originally proposed (back in the 70s)
and implemented (e.g. in MultiLisp in 85, Oz in 95, and others later).
However, there are really only two consistent points in the design
1. Either, futures are objects in their own right, with methods and
everything. Then they should be fully compositional, and never be
equated with their content, even after resolved (because that would
change the meaning of a reference at locally unpredictable points in
2. Or, futures are entirely transparent, i.e. can be used everywhere
as a placeholder for their content. In particular, that means that
'f.then' always denotes the 'then' method of the content, not of the
future itself (even when the content value is not yet available).
Unfortunately, option (2) requires that accessing a future that is not
yet resolved has to (implicitly) block until it is (which is what
happens in MultiLisp and friends). That only makes sense with threads,
> One thing I have been convinced by your message is that it seems necessary
> to provide the lowest-level non-flattening primitives so that people build
> abstractions can that consider promises as values and will want to know
> about nested promise types. It should be possible, but building such
> abstractions doesn't seem like the 80% use case.
> Based on my experience, I remain pretty strong on the fact that flattening
> is a sensible default and really has practical advantages to large-scale
> So, what about the following:
> 1) Providing lowest-level non-flattening primitives so that library authors
> have fine-grained control and can build their own abstraction where they can
> consider promises as values (what is missing in the current API?)
> 2) The API to be used by the average devs (then/catch/done/every/any/etc.)
> has flattening semantics as this is what people with the most experience
> have been advocating for (people with a different experience are still free
> to speak up).
> This API would just happen to be one possible library that can be built on
> top of 1), but one library which semantics has proven to be useful and
> popular among devs.
> Would that satisfy everyone?
Maybe, although I fear that the distinction isn't all that clear-cut,
and library writers will still feel encouraged to build
non-compositional abstractions on top of the high-level API. After
all, one programmer's high-level API is the next programmer's
I have a strong feeling that the request for implicit flattening stems
from the desire to somehow have your cake and eat it too regarding the
choice between future semantics (1) and (2) above. Even if you want
flattening, isn't an explicit flattening method good enough?
More information about the es-discuss