アイデンティティに取り組む前に、平等によって私たちが意味することをもう少し正確に定義しましょう。2つのことは、区別できない場合にのみ等しいと言えます(参照:識別不能のアイデンティティ)。つまり、2つのものが等しいかどうかは、検査する手段に依存します。
それをプログラミング用語でもう少し考えてみましょう。私たちの先入観をドアに残して、すべての変数と値が不変であるまったく新しい未知の言語で作業しているとしましょう。上記の定義では、の代わりに使用した場合、またはその逆の場合に異なる結果を生成するプログラムが言語にない場合にのみ、2つの値A
とB
は等しくなります。さんが言ってみましょうと浮かぶ、および式に代入するとき(IEEE 754)され、結果は両方のためにと。確かにと両方ともゼロです。それらは等しいですか?それは依存します-言語は私がゼロのサインを決定することを可能にするあらゆる機能を提供しますかA
B
A
B
_ + 1.0
1.0
A
B
A
B
?そうでない場合、それらは同等です。もしそうなら、そうではないかもしれません。
したがって、2つの値は、サポートする操作のすべての可能な組み合わせに対して同じ結果を与えるときは常に等しいです。特に不変値は、以前にそれらに適用された操作に応じて、異なる結果を生成しません。そのため、2つの変数が同じ値の2つのコピーを指しているのか、または両方が同じコピーを指しているのかは関係ありません。
これは可変性とどのような関係がありますか?変異性は、私たちの言語には、内容を上書きできるメモリセルの概念があることを意味します。言語に可変メモリセルのサポートを追加するとします。
ref <value>
他のすべてとは異なり、に初期化された新しいメモリセルを作成し<value>
ます。
<variable> := <value>
参照セルの内容を上書きします。
!<variable>
参照セルに現在格納されている値を返します。
次に、メモリセルの平等とはどういう意味かを考えてみましょう。と仮定A = ref 0
しB = A
ます。このプログラムを考えてみましょう:
A := 1
print(!_)
ブランクをA
プリント1
に置き換え、B
プリント1
も同様に置き換えます。今、と仮定A = ref 0
しB = ref 0
ます。この場合、上記のプログラムプリントに代入1
し、0
今から、A
およびB
ポイント異なるメモリセルへ。
したがって、2つの参照が同じメモリセルを指しているか、異なるメモリセルを指しているかは重要です。それが重要なので、2つの参照を区別する効率的で一般的な方法があると便利です。それらが保持する値を比較する現在の方法、およびそれらが等しい場合、それらの1つを変更することは、いくつかの理由で厄介です。
- これは、メモリセルに格納されている値が等しいかどうかを比較できるかどうかに依存します。2つの未知の関数が等しいかどうかを判別する一般的な方法がないため(たとえば、これはホールティング問題領域に進出しています)、すべてのタイプに対して平等は意味を成しません。したがって、関数を格納するメモリセルへの2つの参照が与えられた場合、それらが保持する関数を等しいかどうか比較することはできません。
- それは、2つの参照のうちの1つに割り当てることができる値があるかどうかに依存します。そのため、言語のすべての型で等価性が理にかなっている場合でも、比較する各型の値にアクセスする必要があります。その型の値を作成すると副作用がある場合はどうなりますか?
- 参照の1つを変更するために使用する参照値は、メモリセルがすでに持っている値とは異なる必要があるため、実際には2つの値が必要です。
- 異なる型の参照を比較するコードは、使用する2つの値を保存するとまったく同じに見えます。
- プログラムの意味が変更されないように、変更した参照の値をバックアップして復元する必要があります。
したがって、2つの参照が同じ可変メモリセルを指しているかどうかを直接チェックする操作を言語が提供することは有用です。このような関数は、不変の値には意味がありません。実際、それは実に有害だと思います。2つ1
のがメモリ内の異なる場所に格納されているかどうかを確認する方法が存在する場合、どちらか一方を渡すかどうかを気にするプログラムがある可能性があります1
。自分に「正しい1
」権利があるかどうか、本当に心配したくない。数学はそのままで十分難しいです!したがって、メモリの等価性をチェックできることは、主に変更可能な型に役立ちます。