[e-lang] async AND in E versus Joe-E/ref_send
Tyler Close
tyler.close at gmail.com
Sun Mar 11 10:48:51 CDT 2007
So in an attempt to stoke the fires a bit, here's a side-by-side
comparison of asynchronous logical AND in E versus in Joe-E/ref_send.
First in E, from MarkM's thesis:
def asyncAnd (answers ) {
var countDown := answers.size()
if (countDown == 0) { return true }
def [result , resolver ] := Ref.promise()
for answer in answers {
when (answer) -> {
if (answer) {
if ((countDown -= 1) == 0) { resolver.resolve(true) }
} else {
resolver.resolve(false)
}
} catch ex { resolver.smash(ex) }
}
return result
}
Now in Joe-E/ref_send:
static public Promise<Boolean>
and(final Eventual _, final Promise<Boolean>... condition) {
if (0 == condition.length) { return ref(true); }
final Channel<Boolean> x = _.defer();
final Var<Integer> remaining = var(condition.length);
for (final Promise<Boolean> test : condition) {
_.when(test, new Do<Boolean,Void>() {
public Void
resolve(final Boolean value) {
if (value) {
remaining.put(remaining.cast() - 1);
if (0 == remaining.cast()) { x.head.resolve(true); }
} else {
x.head.resolve(false);
}
return null;
}
public Void
reject(final Exception reason) { return x.head.reject(reason); }
});
}
return x.tail;
}
The above implementations are 15 and 23 lines respectively, making the
Joe-E/ref_send implementation about 50% longer. The difference in line
count primarily comes from E having special syntax for a when block,
whereas the Joe-E/ref_send implementation can only use Java's inner
class syntax. The big advantage of the Joe-E/ref_send implementation
is that it can be written and debugged using any Java IDE and runs
with Java's performance characteristics.
Also notice the extra parameter in the Joe-E/ref_send implementation,
the Eventual. The ref_send library is implemented in conforming Joe-E
code, and so cannot have static mutable state. This requirement means
that E's approach of making the event loop ambient authority cannot
work in ref_send. The event loop must be an explicit argument to
methods. So far, I haven't found this explicit argument passing too
much of a burden. This design also has the advantage that I can deny
some code access to the event loop. So for example, I can make a
library call and when it returns I know for sure that it is done
executing since it doesn't have access to the event loop, which would
enable it to schedule future execution.
In ref_send, I've appropriated the much maligned '_' character to
identify all eventual operations. The Eventual operator itself is by
convention held in a variable named "_", and all eventual references
are suffixed with an '_'. These conventions mean that the programmer
can quickly identify all the eventual operations in a body of code
just by scanning down the page looking for the '_' character. I think
this convention makes change in flow of control standout nicely from
the surrounding code, without being heavyweight.
Tyler
More information about the e-lang
mailing list