float pi = 3.14;
float (^piSquare)(void) = ^(void){ return pi * pi; };
float (^piSquare2)(void) = ^(void){ return pi * pi; };
[piSquare isEqualTo: piSquare2]; // -> want it to behave like -isEqualToString...
3 に答える
コンパイラの実装と言語設計の問題は別として、あなたが求めているものは、おそらく決定不可能です(100%同一のプログラムを検出することだけを気にしない限り)。2つのプログラムが同じ関数を計算するかどうかを決定することは、停止性問題を解くことと同じです。これはライスの定理の典型的な結果です。チューリングマシンの「興味深い」特性は決定不可能です。「興味深い」とは、一部のマシンでは真であり、他のマシンでは偽であることを意味します。
楽しみのために、ここに証拠があります。EQ(b1、b2)と呼ばれる2つのブロックが同等かどうかを判断する関数を作成できると仮定します。次に、その関数を使用して停止性問題を解決します。新しい関数HALT(M、I)を作成して、チューリングマシンMが入力時に停止するかどうかを通知します。
BOOL HALT(M,I) {
return EQ(
^(int) {return 0;},
^(int) {M(I); return 0;}
);
}
M(I)が停止した場合、ブロックは同等であるため、HALT(M、I)はYESを返します。M(I)が停止しない場合、ブロックは同等ではないため、HALT(M、I)はNOを返します。ブロックを実行する必要がないことに注意してください。仮想のEQ関数は、ブロックを見るだけでそれらの等価性を計算できます。
これで停止性問題は解決しましたが、これは不可能であることがわかっています。したがって、EQは存在できません。
これは不可能だと思います。ブロックは、おおまかに高度な機能 (グローバルまたはローカル変数にアクセスできる) と見なすことができます。関数の内容を比較できないのと同じように、ブロックの内容を比較することはできません。
低レベルの実装を比較することしかできませんが、同じ内容の 2 つのブロックが実装を共有することをコンパイラが保証するとは思えません。