1 つのパターンは、テストの結果を表すオブジェクトと、実行するブロックを表すオブジェクトを持つことです。結果オブジェクトは選択関数をオーバーライドしているため、Bool に choose(T positive, T negative) がある場合、Bool.TRUE は正の引数を返し、Bool.FALSE は負の引数を返します。smalltalk ファミリー言語の単純な実装は、そのように機能します。
while ループをその形式でエンコードするには、x と y を比較した結果に対して choose メソッドを呼び出して、while ループの内側のブロックを呼び出すかどうかを決定する必要があります。また、そのブロックは比較と選択を使用して、 x の値。より文字通りの翻訳は、x を z に設定するブロックまたは何もしないブロックのいずれかを選択することです。代わりに、choose を使用して x を同じ値に戻します。
明らかに、この単純なケースではやり過ぎで非効率的です。
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();
}
}