Un patrón es tener objetos que representan el resultado de la prueba, y los objetos que representan el bloque a ejecutar. Los objetos resultantes han anulado las funciones de selección, por lo que si Bool tuviera una opción (T positivo, T negativo), entonces Bool.TRUE devolvería el argumento positivo y Bool.FALSE devolvería el negativo. Las implementaciones ingenuas de los lenguajes de la familia smalltalk funcionan así.
Para codificar su ciclo while de esa forma, necesita llamar al método choose sobre el resultado de comparar xey para determinar si se llama al bloque dentro del ciclo while, y ese bloque también usa compare y elige establecer el valor de x. Una traducción más literal sería elegir ya sea un bloque que establece x a z o uno que no hace nada; en su lugar, solo utiliza elegir establecer x de nuevo en el mismo valor.
Obviamente, es excesivo e ineficiente en este caso simple.
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();
}
}
@ken Gracias por detectar el error tipográfico. Lo hago mucho. – WolfmanDragon