OCaml 標準ライブラリ探訪 #1.1 Pervasives 補遺

関連リンク:
OCaml 標準ライブラリ探訪 #0
OCaml 標準ライブラリ探訪 #1: Pervasives


御好評のようでいくつか twitter でつぶやきを頂いております。私がフォローもしくはキーワード OCaml で監視して見つけたモノのみしか追えませんが、、、まあつぶやいた皆様にとっては自明な事かもしれませんが、tutorial として価値がありそうなので。

そうえいば、 Pervasives と既定義の違いはなんなんだろう。全部 Pervasives でいいような。
ytominoさん

predefined.ml で既定義になっているデータ型、コンストラクタ、例外はコンパイラ内部で型推論時や最適化時に使用されています。例えば、array.(x) (array の要素アクセス) という式では x の型は int でなければいけませんが、この型推論を行うには int 型の存在をコンパイラが知っている必要があります。初期値のない labeled optional argument の適用が省略された際には、optional argument には None が束縛されます。例えば、

let f ?x () = x in f ()

let f ?x () = x in f ?x:None ()

のようにコンパイラ内部で変換されます。この際、コンパイラは None という option 型のコンストラクタの情報(無引数のコンストラクタで、整数0にコンパイルされるべき等)を知っていなければなりません。このようなコンパイラ内部で事前に知っている必要のあるデータ型や例外は Pervasives ではなく、既定義とした方が都合が良いのです。別に Pervasives で宣言しても良いのですが、実装が面倒になるはずです。

そういえば、let (_: string) = readline () inのように書いてるなあ。ignoreだと引数が増えたときにハマった経験から。
ytominoさん

これは、ignore (f x) と書いていたが、関数 f に引数を足したために、 f x がいつの間にか total application (全適用)ではなく partial application(半適用) になってしまった。そのため、起こるはずの計算や副作用が起こらずバグになってしまった。本当は新しい引数を適用して ignore (f x y) とでもしなければならなかったのに、ignore のおかげでそれに気づけなかった。ということだと思います。確かに大昔の OCaml ではそういう事があったように記憶しています。
現在では ignore (f x) で f x が partial application の場合は Warning F が発生するのでそれで捕まえるのがよろしいと思います。

OCaml の variant constructor の大小関係って実装がたまたまそうなってるのか、一応仕様なのか、どっちなんだろう。調べればすぐにわかるのかな。OCaml ではあんまり仕様とか実装とか言わない気もするけど
mametterさん

C言語とのインターフェースを取るときに variant constructor のタグの順番が重要になるので、タグのつき方はマニュアルで規定されており、仕様といっていいでしょう。そのタグを使って自動的に大小関係を決めるのは、、、仕様とは呼べないですね。そもそも

type weekday = Monday | Tuesday | ... | Friday | Saturday | Sunday
let is_weekday wd = wd < Saturday

など、大小関係を直接利用したプログラミングはわかり難いだけでなく、コンストラクタの宣言順が変わる可能性もあるので (Sunday は一番始めか、それとも後か?)、避けるべきです。

自動的な大小関係が重要なのはもっと間接的な所、多くのデータ型が自動的に comparable (比較可能)になり、すぐに 比較を使った派生データ構造(例えば btree を使った集合 (Set.Make)など)が作成できることです。Comparable になる、のは仕様とまで言い切っていいのでは無いでしょうか。

もちろん OCaml に正式な仕様などないので、ここで言う仕様は、OCaml 3.x の内はまず挙動が変わることがないと私が太鼓判を押す機能っていう意味です。

ちなみに大昔の CAML では大きさはコンストラクタの alphabetical order でした。多分タグも alphabetical order にソートされていて、それを比べていたと記憶しています。