- From: David Sheets <kosmo.zb@gmail.com>
- Date: Sat, 27 Apr 2013 17:55:33 +0100
- To: Ron Buckton <rbuckton@chronicles.org>
- Cc: David Bruant <bruant.d@gmail.com>, "Tab Atkins Jr." <jackalmage@gmail.com>, es-discuss <es-discuss@mozilla.org>, "Mark S. Miller" <erights@google.com>, "public-script-coord@w3.org" <public-script-coord@w3.org>, Mark Miller <erights@gmail.com>, Dean Tribble <tribble@e-dean.com>
On Sat, Apr 27, 2013 at 5:21 PM, Ron Buckton <rbuckton@chronicles.org> wrote: > Here is a case where flattening helps: > > function executeAndWaitForComplete(command) { > return getJSON(commandUrl + command) > .then(function (commandResult) { > if (commandResult.complete) { > return commandResult.model; This gets automatically lifted into Future, resulting in Future<typeof commandResult.model>. > } > var statusUrl = commmandResult.statusUrl; > return pollForCommandComplete(statusUrl); This is always a Future and becomes the result of executeAndWaitForComplete with type Future<typeof commandResult.model>. > }) > } > > function pollForCommandComplete(statusUrl) { > return new Future(function(resolver) { > var poll = function (pollResult) { > if (pollResult.done) { > resolve.resolve(pollResult.model); > } > else { > setTimeout(function() { > getJSON(statusUrl).done(poll, resolver.reject); > }, 500); > } > } > getJSON(statusUrl).done(poll, resolver.reject); > }); > } > > In this example, the server will receive a command from the client and will > process it asynchronously. The client then needs to poll an endpoint to > check for completion of the command. Just using Futures, flattening is > helpful here. Without flattening, executeAndWaitForComplete would could > return either a Future<object> OR return a Future<Future<object>>. I think the major point of confusion in these discussions is the result of the framing of the discussion in terms of "flattening". I believe most beneficial viewpoint is that of "autolifting". That is, the exceptional case is not when the function argument of "then" returns a Future+ that gets "flattened" but rather when the function argument of "then" returns a non-Future that gets automatically lifted into a Future. This change in perspective is non-obvious because in many of these APIs there is no succinct lifting operation to make a Future from another value. This is a major reason why something like Future.of (Future.accept) is important. > In a non > flattening world, the developer would have to change the function to: > > function executeAndWaitForComplete(command) { > return new Future(function(resolver) { > getJSON(commandUrl + command) > .done(function (commandResult) { > if (commandResult.complete) { > resolver.resolve(commandResult.model); > } > var statusUrl = commmandResult.statusUrl; > pollForCommandComplete(statusUrl).done(resolver.resolve, > resolver.reject); > }, resolver.reject) > }); > } In a non-flattening (and non-autolifting) world, this would be the code: function executeAndWaitForComplete(command) { return getJSON(commandUrl + command) .then(function (commandResult) { if (commandResult.complete) { return Future.accept(commandResult.model); } var statusUrl = commmandResult.statusUrl; return pollForCommandComplete(statusUrl); }) } The only difference here is that commandResult.model is explicitly wrapped. This is because the signature of then is actually Future<a> -> (a -> Future<b>) -> Future<b>. David
Received on Saturday, 27 April 2013 16:57:28 UTC