Why would I do that? Because I can :-) But seriously, using continuations in a language entirely unsuited for it is a good way to experience the tradeoffs of different styles of languages, as well as a way to learn more about how continuations work.
This code is entirely different from my Arc version, mainly because in the Arc version I decided to see if the
Because Java doesn't support first-class functions, every continuation function needs to be wrapped in a class that implements an interface, which I unimaginatively call
On the whole, mondo-bizarro worked better in Java than I expected; no Greenspunning required. It produces the expected 11213 output, proving it works. I think the Java code is actually easier to understand, since everything is explicit.
I have also found it entertaining to implement some of the complex SICP exercises in Java; maybe I'll post details later.
(The title of this article is, of course, a homage to Mathematics Made Difficult.)
Here's the code.
throw/catch
idiom could replace call/cc
; the Java code is much closer to the original Scheme. Because Java doesn't have first-class continuations, I used the Continuation-passing style of explicitly passing continuations around. Then call/cc
is simply replaced with use of the current continuation.
Continuation
. The "let" also turns into an object creation, resulting in another class. This results in a fair bit of boilerplate to handle all these classes compared to the Scheme code, but the Java code maps recognizably onto the Scheme code.
/**
* Mondo-Bizarro ported to Java.
* Based on mondo-bizarro by Eugene Kohlbecker
* ACM SIGPLAN Lisp Pointers, Volume 1, Issue 2 (June-July 1987) pp 22-28
*/
/* Original Scheme code:
(define mondo-bizarro
(let (
(k (call/cc (lambda (c) c)))
)
(write 1)
(call/cc (lambda (c) (k c)))
(write 2)
(call/cc (lambda (c) (k c)))
(write 3)))
*/
interface Continuation {
public void run(Continuation c);
}
public class Mondo implements Continuation {
public static void main(String argv[]) {
Continuation c = new Mondo();
c.run(c);
}
public void run(Continuation c) {
Continuation let = new Let();
let.run(c);
}
class Let implements Continuation {
Continuation k;
public void run(Continuation c) {
k = c;
System.out.println("1");
k.run(new C2());
}
class C2 implements Continuation {
public void run(Continuation c) {
System.out.println("2");
k.run(new C3());
}
}
class C3 implements Continuation {
public void run(Continuation c) {
System.out.println("3");
}
}
}
}
Computer history, restoring vintage computers, IC reverse engineering, and whatever
Continuations made difficult
For a challenge, I translated the "mondo-bizarro" Arc Continuation Puzzle into Java.
No comments:
Post a Comment