Re: Resolving Futures w/multiple values

The problem I find with this suggestion is where do you draw the line?  There are already good mechanisms to handle passing around tuples.  Why make the Futures API also provide custom support for tuples?  And if it does, why stop there?  Wouldn't it also be nice if the futures could capture our context and set it when calling our callbacks?


someFuture.done(callback, context); // callback will be called with "context" as its 'this'.

I mean, we have Function.bind, but wouldn't this be more convenient since maybe some other old-style async API provided the convenience and not also providing the same convenience might make it frustrating/ugly?  I'm sure people could think up other things that might be convenient, but they aren't necessary and their exclusion does not reduce the functionality of the API in any meaningful way.

Instead of making every new API that comes out re-implement features the language already supplies, why doesn't the hypothetical API that wraps the node.js-style methods shield you from this concern and provide a way to wrap the callbacks also?

callback = function(bar, baz) { ... }; // old-style callback that I now want to use with future API
futureFoo = wrap(foo);
futureFoo(param1, param2).done(wrapCallback(callback)); // wrapCallback will unbox for me.


This avoids a whole nest of problems related to chaining futures and waiting for a collection of Futures where each future might resolve to a different number of results.  It would be frustrating and mystifying if you lost the extra results just because you chained your futures.

--
Brandon



________________________________
 From: Dave Longley <dlongley@digitalbazaar.com>
To: Bjoern Hoehrmann <derhoermi@gmx.net> 
Cc: www-dom@w3.org; Anne van Kestern <annevk@annevk.nl>; slightlyoff@chromium.org 
Sent: Wednesday, April 24, 2013 10:12 AM
Subject: Re: Resolving Futures w/multiple values
 

On 04/24/2013 11:01 AM, Bjoern Hoehrmann wrote:
> * Dave Longley wrote:
>> In order to convert this continuation-passing style API to a Future, a
>> wrapper creates a new function that wraps the async operation and passes
>> a callback that will call reject() if a non-null 'err' parameter is
>> defined and resolve() with an array containing both 'bar' and 'baz'
>> otherwise. The code to use such a wrapper and its resulting Future might
>> look like:
>>
>> futureFoo = wrap(foo);
>> futureFoo(param1, param2).done(function(value) {/*value is [bar,
>> baz]*/}, function(err) {})
>>
>> This will be a bit odd for anyone used to using the library, but it is
>> at least usable, unless 'bar' can be either an array or an object and
>> 'baz' is optional. Then the results are indeterminate.
> I don't see the problem here. `value` would never be `bar`, it would be
> `[bar, ...]` because you always box the value to avoid this problem.

It wouldn't be a problem if you *always* box the value. A possible 
solution to this problem would be to provide two API methods for 
transforming node.js-style async operations -- one that always boxes 
(for those operations with multiple parameters) and one that doesn't 
(for those operations with a single parameter, to avoid the annoyance of 
having to unbox).

However, I think that if the annoyance of dealing with boxing/unboxing 
could be avoided, that would be preferable. It seems like an unnecessary 
limitation and, my guess would be, a lot of developers who end up having 
to wrap continuation-passing style functions to unify under a 
Promises/Futures API would not understand the limitation and would also 
find it frustrating/ugly. Whether or not that will hurt adoption -- or 
if the community cares about that adoption is unclear. It would be nice 
if everything just continued to work "as is".

-- 
Dave Longley
CTO
Digital Bazaar, Inc.

Received on Wednesday, 24 April 2013 16:15:35 UTC