ISSUE-124: Futures / Order of parameters (was: Re: Request for JSON-LD API review)

On 04/16/2013 07:55 PM, Tab Atkins Jr. wrote:
>> We also considered Futures but decided that introducing a normative
>> dependency to the DOM spec is not acceptable at this stage.

This was one of the reasons, but wasn't the main reason. The main reason
was that it wasn't clear what problem was being solved by replacing the
node.js-style callbacks in the JSON-LD API with futures. More on this below.

> Worrying about dependencies falls into the "technical purity" bucket,
> and your ladder of constituencies is:
> 
> Technical Purity < Implementors < Authors < Users

Yes, agreed.

> If there is a correct way to do things, but it would introduce a new
> dependency, your job is to do the correct thing and then figure out
> how to route around the bureaucracy.  Anything else is abandoning your
> responsibility toward all the other constituencies.

Also agreed. So, let's focus on the correct way to do things in this
instance and forget about the DOM4-dependency.

> In this case, your API is a textbook example of Futures.  You have an
> async call which returns a single value, or an error.  You can't get
> much more perfect than that.

For those that aren't tracking the discussion, we had a discussion in
the #whatwg channel yesterday about the JSON-LD API and Futures:

http://krijnhoetmer.nl/irc-logs/whatwg/20130417#l-198

I asked Tab to write a blog post about DOM4 Futures just to make sure
that we weren't missing anything important. Tab kindly spent the time
and put together a really good blog post on futures:

http://www.xanthir.com/b4PY0

The blog post is a good read for what is planned for Futures in DOM4. I
do have follow-up questions on the blog post, which I'll go into below.
But before that, some background.

The JSON-LD API uses node.js-style callbacks. We made this technical
decision because it was compatible with both server-side and client-side
code in JavaScript. It was also compatible with asynchronous-style
programming in Ruby and Python.

It's also important to note that node.js started out with futures as a
design paradigm and moved away from that design for a number of very
good reasons:

http://www.futurealoof.com/posts/broken-promises.html

Tab's post doesn't address the fundamental problems with DOM4 Futures:

1) The spec isn't done. DOM4 Futures are too experimental for
   production at this point.
2) They're not supported in many languages in the same way as DOM4,
   so anyone wanting to implement the JSON-LD API would have to
   implement DOM4 Futures.
3) Futures aren't as popular yet as callback management. Just taking
   the two most popular libraries for flow management in node.js
   (async and q). Callback management (async) has 1,000 libraries that
   depend on it, futures (q) has around 258.
4) Mixing callback management with Futures leads to a great deal of
   pain for developers. It requires each software library to have
   two flow-control versions. One for callback management and one for
   futures.

The benefits of using futures instead of callback management seem to
boil down to personal preference more than a clear technical advantage
of one over the other. There are benefits to using futures over callback
management, there are also benefits for callback management over futures.

Now on to the specifics of Tab's blog post:

Reason 1: Chaining
------------------

You can chain just as easily using the async module:

https://github.com/caolan/async/blob/master/README.md

It works just as well in the browser:

https://github.com/caolan/async/blob/master/README.md#in-the-browser

Reason 2: More Chaining (Deep nesting)
--------------------------------------

Async, and many of the other callback management libraries, prevent deep
nesting:

https://github.com/caolan/async/blob/master/README.md#quick-examples

Reason 3: Linear callback growth
--------------------------------

This is annoying to deal with, although there aren't many cases that
we've found in practice where this leads to deep nesting. I'd say that
this is a clear win for futures, but it might be solving a problem that
many developers don't have today.

Reason 4: Errors are easy to deal with
--------------------------------------

This is also a solved problem in many of the callback management
libraries. There is one error function at the end, if any of the
functions called in a series or in parallel throw an error, all
subsequent calls are canceled and the error callback is called instead:

https://github.com/caolan/async/blob/master/README.md#seriestasks-callback

Reason 5: Future combinators
----------------------------

There are 3 proposed combinators for the DOM4 Futures spec. Async has
over 10 combinators defined (depending on what your definition for a
'combinator' is):

https://github.com/caolan/async/blob/master/README.md#control-flow

15 combinators exist because the 3 that DOM4 Futures defines are not
enough to cover the use cases that developers have found in the wild.

Conclusion
----------

I remain unconvinced that shifting the current JSON-LD API over to a
DOM4 Future's approach is the way to go. I do accept that this may be
the wrong decision in the long term if everyone decides to move over to
futures. In an attempt to mitigate the risk, perhaps we should also
define a JSON-LD Futures API in another spec? Maybe we should rename the
current API to JSON-LD Callback API?

Tab, Boris, did I misunderstand anything above? Did I miss a key concept
with Futures that are not covered already by async (or many of the other
callback management libraries)?

-- manu

-- 
Manu Sporny (skype: msporny, twitter: manusporny, G+: +Manu Sporny)
Founder/CEO - Digital Bazaar, Inc.
blog: Meritora - Web payments commercial launch
http://blog.meritora.com/launch/

Received on Wednesday, 17 April 2013 14:51:05 UTC