On Dec 7, S. Dale Morrey wrote:
> One thing that I admit I am struggling with, is the idea of functions not
> returning values.  Obviously, this isn't a limitation in the language
> itself and more a matter of style. But it seems like most of the libs I'm
> working with want me hand them a function (pointer?) to call back rather
> than returning a value.  That works fine for asynchronous code.  However
> there are many times I just plain need the code to block and wait for a
> return value, then do something with that value.  I don't want to have to
> create a new function just to deal with every single value I need.

Callback programming like this is hard to wrap your head around, but
it's the simplest way to handle asynchronous events.  You're not alone
in considering it somehow backwards; the Twisted framework takes its
name from the brain warping required to do it right.

The problem is that Javascript interpreters are single-threaded.  They
get an event, and process any associated handlers in turn.  However,
the ability to collect new events, and to process multiple simultaneous
events in a timely fashion, requires that each event not block.  Ever.
So Javascript simply doesn't give you any blocking primitives.

Otherwise, pages go entirely unresponsive, particularly if they're
heavily based on client-side actions.

> I guess this is what they call functional programming.  Nevertheless I
> don't generally like anonymous inner classes in Java (it tends to break
> code reuse) and I'm really not a fan of this in Javascript.

Functional programming is the notion that functions (almost) never have
side effects.  Think Haskell.  It makes mathematicians happy, because it
enables them to prove that programs are correct, but it requires even
more brain warping and puzzle solving to do any real work.

What it has contributed to more mainstream (read: usable) languages is
the idea of functions as a first-class data type.  Once defined, a
function can be passed around as if it were any other value.  That leads
to convenient second-order functions, as well as callbacks.

The good news is that Javascript functions are much easier to reuse than
Java's anonymous inner classes, as well as easier to define precisely
where you need them.  Where the required effect is so specific that it
wouldn't be reused, it would frequently be defined inline:

    barFunc(paramVal, function(result) { process(result[0].value); });

Any lines that would have gone below the function call are simply
wrapped in another block, with perhaps another layer of indentation.

> But maybe I'm missing something here.  Other than asynchronous method
> calls, is there any valid reason to take the second approach rather than
> the first?

No, it's pretty much all about asynchronicity.  When a library requires
a callback in order to collect a result, it's because the function might
need to wait for something in order to determine the result, or for
consistency with other such functions.

The good news is that asynchronous primitives are much easier to treat
as a synchronous system than synchronous primitives are to morph into
asynch systems; the latter often involves either threads or gradual
transitions to a duplicate API.  On the other hand, I have more respect
for languages that allow the asynchronous aspect to be swept under the
rug: Google's Go lang, for example, appears to have synchronous-looking
calls that transfer control back to an event loop until the result is
ready, while offering a simple keyword to let function calls run in the
background.  Of course, that requires either suspendable stack frames or
multiple threads, as well as an event loop.

Anyone care to implement that kind of behavior for Javascript?  Of
course, we'll need to wait for Microsoft to re-implement the new spec
before it can safely be used on websites...

- Eric

/*
PLUG: http://plug.org, #utah on irc.freenode.net
Unsubscribe: http://plug.org/mailman/options/plug
Don't fear the penguin.
*/

Reply via email to