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. */