// The factoral function in continuation-passing style, in Java
// sestoft@dina.kvl.dk 2002-04-03, 2003-03-19
// A Cont object is a continuation: it has a method k that given the
// result of a subcomputation will return the final result:
interface Cont {
int k(int v);
}
// Calling the two versions of factorial:
class Factorial {
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
System.out.println(facc(n,
new Cont() {
public int k(int v) {
return v;
}
}));
System.out.println(faci(n,
new Cont() {
public int k(int v) {
return v;
}
}));
}
// A continuation-passing version of factorial. This is a straight
// translation of the Standard ML version:
static int facc(final int n, final Cont cont) {
if (n == 0)
return cont.k(1);
else
return facc(n-1,
new Cont() {
public int k(int v) {
return cont.k(n * v);
}
});
}
// Another continuation-passing version of factorial. Since facc
// above is tail-recursive, it can be rewritten as a loop. This
// shows how it builds up a continuation and finally applies it:
static int faci(int n, Cont cont) {
while (n != 0) {
cont = new FacCont(n, cont);
n--;
}
return cont.k(1);
}
}
// Auxiliary class to implement faci. Needed for Java-technical
// reasons; a local inner class can refer only to `final' variables in
// the enclosing method, but faci must update the cont variable in the
// loop.
class FacCont implements Cont {
private final int n;
private final Cont cont;
public FacCont(int n, Cont cont) {
this.n = n; this.cont = cont;
}
public int k(int v) {
return cont.k(n * v);
}
}