The current callback method employed by async uses the first argument as an optional error argument, much like the NodeJS callback pattern. This is suitable for NodeJS, and quite useful as the default, but it is not quite as suitable for targets which don't naturally support variadic function. This can especially be a problem for callbacks which return a large number of proper values, having to pad these for an error call.
To support such targets, I suggest using a two-callback pattern, as is commonly used in jQuery and other targets:
public function doAsync(callback_success : Void->Void, callback_error : Dynamic->Void) : Void;
To prevent backwards compatibility issues, I suggest the following syntax:
class MyClass implements async.Build
{
@asyncCbErr static function foo(x: Int) : Many<Int, Int>
{
var a = 1;
if (x > 0)
[[a, x]] = foo(x-1);
return many(a*x, a+x);
}
}
This is translated to:
class MyClass
{
static function foo(x: Int, cb : Int->Int->Void, cberr : Dynamic->Void) : Void
{
var a = 1;
function after() {
cb(a*x, a+x);
}
if (x > 0)
foo(x-1, function(_a, _x) {
a = _a;
x = _x;
after();
}, cberr);
else after();
}
}
The new meta, and the double-brackets prevent any ambiguity, since those do not form any meaningful interpretation in the current syntax.
An added advantage is that passing cberr forward in calls is less expensive than adding a branch on every callback, and can be inlined by optimizing compilers in some cases.
For full compatibility, this:
@asyncCbErr static function a() : Void
{
[[]] = a();
[] = b();
}
@async function b() : Void
{
[[]] = a();
[] = b();
}
Should translate to this:
static function a(cb : Void->Void, cberr : Dynamic->Void)
{
a(function() {
b(function(err) {
if (err != null) {
cberr(err);
return;
}
cb();
});
}, cberr);
}
static function b(cb : Dynamic->Void)
{
a(function(){
b(function(err) {
if (err != null) {
cb(err);
return;
}
cb(null);
});
}, function(err) {
cb(err); // This can probably be optimized for the case where cb takes no more parameters
});
}
The current callback method employed by async uses the first argument as an optional error argument, much like the NodeJS callback pattern. This is suitable for NodeJS, and quite useful as the default, but it is not quite as suitable for targets which don't naturally support variadic function. This can especially be a problem for callbacks which return a large number of proper values, having to pad these for an error call.
To support such targets, I suggest using a two-callback pattern, as is commonly used in jQuery and other targets:
To prevent backwards compatibility issues, I suggest the following syntax:
This is translated to:
The new meta, and the double-brackets prevent any ambiguity, since those do not form any meaningful interpretation in the current syntax.
An added advantage is that passing cberr forward in calls is less expensive than adding a branch on every callback, and can be inlined by optimizing compilers in some cases.
For full compatibility, this:
Should translate to this: