One pattern is to have objects which represent the result of the test, and objects which represent the block to execute. The result objects have overridden selection functions, so if Bool had a choose(T positive, T negative) then Bool.TRUE would return the positive argument and Bool.FALSE would return the negative. Naive implementations of smalltalk-family languages work like that.
To encode your while loop in that form, there needs to call the choose method on the result of comparing x and y to determine whether to call the block for the inside of the while loop, and that block also uses compare and choose to set the value of x. A more literal translation would be to choose either a block which sets x to z or one which does nothing; instead it just uses choose to set x back to the same value.
Obviously it's overkill and inefficient for this simple case.
public class WantonPolymorphism {
static class Int32 {
final int value;
Int32 ( final int value ) { this.value = value; }
Compare compare ( Int32 other ) {
// Java runs out of turtles at this point unless you use
// an enum for every value
if ( this.value < other.value ) return Compare.LESS;
if ( this.value > other.value ) return Compare.GREATER;
return Compare.EQUAL;
}
}
enum Compare {
LESS {
<T> T choose (T less, T equal, T greater) { return less; }
},
EQUAL {
<T> T choose (T less, T equal, T greater) { return equal; }
},
GREATER {
<T> T choose (T less, T equal, T greater) { return greater; }
};
abstract <T> T choose (T less, T equal, T greater) ;
}
interface Block { Block execute () ; }
/**
* Main entry point for application.
* @param args The command line arguments.
*/
public static void main (String...args) {
Block block = new Block() {
Int32 x = new Int32(4);
Int32 y = new Int32(3);
Int32 z = new Int32(2);
public Block execute () {
System.out.printf("x = %d, y = %d, z = %d\n", x.value, y.value, z.value);
return x.compare(y).choose(done, done, new Block () {
public Block execute () {
x = x.compare(z).choose(x,x,z);
return x.compare(y).choose(done, done, this);
}
});
}
Block done = new Block () {
public Block execute () {
System.out.printf("x = %d, y = %d, z = %d\n", x.value, y.value, z.value);
System.exit(0);
return this;
}
};
};
for(;;)
block = block.execute();
}
}