Continuations continued

April 30, 2019 continuations java

Continuations

Update: I amended the implementation to use Lambdas instead of requiring you to derive from the Continuations class. The shenanigans to get ‘yield’ to work are distinctly sketchy though. Be warned.

From the ‘code fished out from under the bed’ department, this is a little entertainment I worked out a few years ago. It was up for a while on another blog that I later shuttered. Having dug it out again I’ve removed some of the rougher edges and updated the codebase to Java 11.

The essence of this exercise is that I read Continuations for curmudgeons and thought it would be neat to see if I could create something with a similar kind of syntax for Java. This was early in 2007, so Java 6 was still reasonably fresh.

In Sam’s article he defines a Fibonacci continuation as follows:

def fib():
     yield 0
     i,j = 0,1
     while True:
       yield j
       i,j = j,i+j

Disregarding boilerplate (observe, an entire deck of cards stuffed up my sleeve) my library allows some fairly similar code to be written:

yield(0);
var i = 0;
var j = 1;
while (true) {
   yield(j);
   final var current = i + j;
   i = j;
   j = current;
}

Adding back in the boilerplate, though, that looks like this:

private final Iterable<Integer> fibonacciContinuation = ContinuationBuilder.build(() -> {
   yield(0);
   var i = 0;
   var j = 1;
   while (true) {
      yield(j);
      final var current = i + j;
      i = j;
      j = current;
   }			
});

Imports are still omitted here, but only because as an eternally corrupted Java dev I consider them to be the job of the IDE.

Anyway, I think this is a reasonably creditable effort, though it does mainly succeed in showing how much terser Python code can be than the notoriously verbose Java even after a few years of evolution! Don’t get me wrong; I enjoy Java a lot - but this sort of exercise is not where it excels.

Such as it is, you’ll find it on Github at https://github.com/dcminter/continuations.

What’s the downside you ask? It creates a daemon thread for each continuation instance. It probably has lurking horrors of race conditions and whatnot (that use of rawtypes in ThreadLocal is particularly suspect). Oh, and it’s not like I’ve ever really found myself thinking “Oooh, yes, continuations is exactly what I need right now!” But if I ever do… I’ll probably step out for a bracing cup of tea and have a re-think rather than use this library.

Good luck! Don’t blame me.