データの(あるいはデータ型の)大事な性質に次のものがあります。
- 変更可能性(ミュータビリティ)
- 複製可能性(コピーアビリティ)
- 破棄可能性(ディスカーダビリティ)
状態を表すデータは変更可能でないと使い物になりませんが、一方で、変更してはいけないデータを変更してしまうバグは非常に多いものです。変更可能データをギリギリまで少なくして、できるだけ多くのデータを変更不可能(イミュータブル)にしたほうがいいだろうと思います。constとかfinalをイッパイ付けようね、ってことです。それを突き詰めると、一部の関数型言語のように、そもそも変更可能データがない仕様となります。
コンピュータでは、データのコピーが比較的容易ですが、それでも巨大なデータとなるとそうそうコピーはできません。現実的には複製不可能なデータもあるのです。変更不可能データなら、データ共有(シェアリング)によりコピーしたのと同じ効果を得られます。変更可能データでも共有はできますが、マルチスレッドから触ったりするとロクでもなく悲惨なことになったりします。
最近のGC当たり前の環境では、データの破棄はあまり意識されないかもしれませんが、複製(コピー)同様に破棄にもコストがかかります。データの破棄を「忘却」と考えると、忘却にはエネルギーが必要とされるのです。忘却するとは、例えばあるメモリ領域をゼロクリアするようなことです。そのメモリ領域(データ)が変更不可能なら破棄=忘却もままならないことになります。データ自体の変更はせずに、単に管理対象からはずす、つまり存在を忘れる方法もありますが、再利用できないゴミがどんどん溜まります。
変更、複製、破棄、いずれの場合もコスト/エネルギーがかかります。このへんのことは次の記事でも触れています。
さて、対象がデータ型、射が計算処理(computational processing)である圏Cを考えましょう。圏Cが、自然数対象(natural-number object)を持つデカルト閉圏だったりすると、やりたいことは何でもできます。しかし、使ってはいけないデータややってはいけない計算もあるでしょう。逆に言うと、使っていいデータ/やっていい計算がピックアップされているとします。すると、それらの許されたデータと計算は圏Cの部分圏Dを形成するでしょう。
データの変更(ミューテーション)、特に状態遷移はエンドセットEndD(A) = D(A, A) で表現されます。データ型Aが変更不可能だとは、D(A, A) = {idA} のことですから、変更可能は次のように定式化できます。
- ∃f:A→A.(f ≠ idA) (恒等射以外の射がある)
データ型Aの複製可能性は、対角射ΔAがDに入っていることです; ΔA∈D(A, A×A)。データ型Aの破棄可能性は、終対象への唯一射!AがDに入っていることです; !A∈D(A, 1)。複製可能性や破棄可能性が、圏論や線形論理をベースにした計算科学で重要な概念であることは、例えば次の検索をして確認できます。
日常的なデータ処理でも、変更可能性・複製可能性・破棄可能性という3つの性質を意識して、「できるだけ変更不可(イミュータブル)に」「要らないモノはサッサと捨てる」のようなエチケットを守るとトラブルを少なくできますよ。