Commits

camlspotter  committed 72d4f74

finished

  • Participants
  • Parent commits 6c2cc72

Comments (0)

Files changed (1)

File ocaml-tools.rst

 OCaml 開発環境について ~ OCaml コンパイラソース付属ツール
 =============================================================
 
-この文章では 2012年3月での関数型言語 OCaml によるプログラム開発における、必須・重要ツールを紹介する。
+この文章では 2012年12月での関数型言語 OCaml によるプログラム開発における、必須・重要ツールを紹介する。
 まず、OCaml コンパイラ一式をインストールした際に付属する「公式」ツール群から解説する。
+紹介は多岐に渡るので、一つ一つの詳しい説明は行わない。各ツールの細かい情報はそれぞれのドキュメントを参照して欲しい。
 
 ★は重要度。五点満点。
 
 OCaml コンパイラ
 ==========================
 
-現時点での公式最新バージョンは 3.12.1。
+現時点での公式最新バージョンは 4.00.1。
 
-次のリリースバージョンはおそらく 4.00.0。開発中の trunk バージョンは 4.01.0。 
-4.00.0 では GADT と 3.12.1 より使い易い first class module が入っている。
-2012年内のリリース予定だと思われる。
+4.00.1 は基本的に 4.00.0 のバグフィクスリリース。4.00.0 では GADT と 3.12.1 より使い易い first class module が入っている。
 
 このところ OCaml のマイナーバージョンの変わるリリースは一年に一度位。
 バグフィックスパッチやリリースはより頻繁にある。
 OCaml 対話環境。いわゆる REPL(Read-Eval-and-Print Loop)。
 入力は型推論の後 bytecode へとコンパイルされ VM により評価される。
 Bytecode とはいえコンパイルが入るため、インタープリタとは普通呼ばれない。
-
-Real World OCaml programmer は toplevel はまず使わない。
+(Native code へとコンパイルする ocamlnat という対話環境も存在する。ただしまだ「非公式」)
 
 ocaml toplevel の対話環境としての能力はあまり高くない。行の編集や履歴を呼び出したい場合は、
 
-* rlwrap : read line wrapper
+* rlwrap : read line wrapper ( http://utopia.knoware.nl/~hlub/rlwrap/#rlwrap )
 * emacs の shell mode 内などでの実行
 
 で編集能力を強化するのが普通である。
 
-(Native code へとコンパイルする ocamlnat という対話環境も存在する。ただしまだ「非公式」)
+Real World OCaml programmer で toplevel を使うか使わないか…は人により違うようだ。
+Toplevel は値のプリンタがあるので、ライブラリをロードして関数のインタラクティブなテストを行う人がいる一方、私は全く使わない。
 
 ocamlc bytecode compiler ★★★★★
 ---------------------------------------
 OCaml ソースコードを bytecode へとコンパイルするコンパイラ。
-Bytecode プログラムは native code と比べると遅いが、 ocamldebug を使ったデバッグが可能。
+Bytecode プログラムは native code と比べると遅いが、 
+ocamldebug を使ったデバッグが可能。
 
 ocamlopt native code compiler ★★
 -----------------------------------------
 \*.opt コンパイラは native にコンパイルされているため bytecode へとコンパイルされたコンパイラより実行速度が早い。
 (Bytecode 版コンパイラがひどく遅いわけではない。)
 
-ocamlc, ocamlopt 以外のツールにも、 .opt の postfix がついた native code バージョンが存在する。
+ocamlc, ocamlopt 以外のツールにも、.opt の postfix がついた native code バージョンが存在する。
 
-ocamldep ★★★★★
-=================
+依存抽出: ocamldep ★★★★★
+==========================================
 ocamldep は複数の OCaml プログラムファイル間の依存関係を抽出するツール。
 結果は Makefile の依存書式で出力される。通常は、
 ocamldep \*.ml \*.mli > .depend
 Multi-byte char を処理する場合は、 ulex を使うべきである。
 
 Lexical analyser。 Lex のスタイルを踏襲しつつ、アクション等のコードを OCaml プログラムで記述できる。
-そのため、基本的に lexer (字句解析)や正規表現の知識が有用かつ前提である
+そのため、基本的に lexer (字句解析)や正規表現の知識が有用かつ前提。
 ocamllex は \*.mll というアクション等のコードを OCaml プログラムで記述できる。
 \*.mll の例は OCaml コンパイラソースの parsing/lexer.mll を参考にするといい。
 
 Parser generator。こちらは yacc のスタイルを踏襲し、アクション等のコードを OCaml プログラムで記述できる。
 そのため、 yacc の知識が必要。例えば shift-reduce, reduce-reduce の知識がなければ使いこなせない。
 ocamlyacc は \*.mly という拡張子のファイルを受け取り、 parsing rule を解釈し、 \*.ml へと変換する。
-注意すべき点として、 OCaml コード以外のパートでのコメントは (\* ... \*) ではなく、 /\* ... \*/ であることが挙げられる
+注意すべき点、 OCaml コード以外のパートでのコメントは (\* ... \*) ではなく、 /\* ... \*/ であること
 \*.mly の例は OCaml コンパイラソースの parsing/parser.mly を参考に。
 
 ocamllex, ocamlyacc は色々と古臭い部分もあり、イライラすることもあるが、
 ocamlyacc のほぼ上位互換 parser generator として Menhir という外部ツールがある。 Menhir は ocamlyacc と同じ \*.mly ファイルを受け取る上に、エラーメッセージが読みやすいなど良い点が多い。そのため、現在 OCaml で parser generator を使う場合は Menhir を使うことが推奨されている。
 (ユーザに Menhir をインストールさせるのが面倒だと思われる場合は、 Menhir で新しい機能を使わず、デバッグ開発を行い、リリース時には ocamlyacc に戻す、ということも可能。)
 
-Camlp4 pre-processor and pretty printer ★★★
-====================================================
+マクロ/文法拡張システム: Camlp4 pre-processor and pretty printer ★★★
+=======================================================================
 Camlp4 (略称P4) は Pre-Processor and Pretty Printer の4つの P から P4 と呼ばれ、
 自分でパーサーをスクラッチから記述できるだけでなく、 
 OCaml コードでのマクロや文法拡張を実現することもできる強力なツール。
 OCaml 文法拡張を書く際、 ambiguity が少なくなる改良文法 (revised syntax) の二つの文法を
 選ぶことができる。これらの文法を使うかどうかに対応して Camlp4 コマンドも camlp4* から始まる複数のコマンド群からなる。
 
-問題は、 P4 は非常に複雑なツールであるため、 OCaml 本体の正式文法が拡張された場合、それへの追随が遅れることがあること
-(よって、新機能と P4 の組み合わせが使えなかったりする)、そして、ドキュメントがほとんど整備されていないこと、である。
-既存の P4 で書かれた文法拡張を使うだけの場合は P4 でのパーサルールの書き方などを理解する必要はないとはいえ改善が望まれる。
+CamlP4 は OCaml 3.10 同梱版より完全にリライトされ、細かい部分がかなり変更された。そのため、「3.10以前系」のチュートリアルドキュメントは「3.10以降系」には細かい点では違いが多すぎて役に立たない。そして、P4 について日本語/英語で書かれたウェブ上のドキュメントはほとんどが「以前系」についてである。「以降系」のドキュメントはあまりない。
+基本的なアイデアは以前系も以降系も同じなので 古い P4 のドキュメントを読んで 以降系 P4 の基本的な使用方法を理解することは可能であるが、その際には必ず 3.10系 P4 の working example などを参照して細かな違いを把握する必要がある。既存の P4 で書かれた文法拡張を使うだけの場合は P4 でのパーサルールの書き方などを理解する必要はないとはいえ改善が望まれる。
 
-以下は 3.10系 Camlp4 を開発した人が書いた情報。残念ながら全く不十分
+3.10以降系 P4 のチュートリアルとしては Jake Donham の
+Reading Camlp4 http://ambassadortothecomputers.blogspot.com/search/label/camlp4
+は素晴らしい記事であり、推薦する。
+
+以下は 3.10以降系 Camlp4 を開発した人が書いた情報。残念ながら全く不十分
 
 * Camlp4: Major changes : http://nicolaspouillard.fr/camlp4-changes.html
 * Using Camlp4: http://brion.inria.fr/gallium/index.php/Using_Camlp4
 
-3.10系 P4 のチュートリアルとしては Jake Donham の
-Reading Camlp4 http://ambassadortothecomputers.blogspot.com/search/label/camlp4
-は素晴らしい記事であり、推薦する。
-
-インターネット上の P4 の情報を調べる際は、必ずそれがいつの時期に書かれたものか確認すること。
+インターネット上の P4 の情報を調べる際は、必ずそれがいつの時期に書かれたものか、つまり 3.10以前か 3.10以降かを確認すること。
 
 Camlp5 との関係
 -------------------
 Camlp4 とは別に Camlp5 というツールが存在するが、これは OCaml に同梱されていない。
 
-Camlp5 は OCaml version 3.09 まで同梱されていた Camlp4 が引継がれたもので、
-Version 3.10 以降の OCaml 同梱の Camlp4 はリライトされ、その際に大幅に refactoring されている。
-そのため、コードベースとしては 「3.09 までの P4」 および P5 は似ている。 3.10系 P4 は
-それらからかなり離れている。 P5 が P4 より数字が多いため、優れているとか、その逆、という関係ではない。
+Camlp5 は 3.10以前系の Camlp4 が引継がれたもので、コードベースとしては 「3.09 までの P4」 および P5 は似ている。 3.10系 P4 はそれらからかなり離れている。 P5 が P4 より数字が多いため、優れているとか、その逆、という関係ではない。
 なお、 P5 は Coq theorem prover でよく使用されている。
 
-基本的にこれら P4, P5 のアイデアは同じなので 古い P4 および P5 のドキュメントを読んで 3.10系 P4 の基本的な使用方法を理解することは可能であるが、その際には必ず 3.10系 P4 の working example などを参照して細かな違いを把握する必要がある。
-
 P4 と P5 が何故ブランチしたか、はさまざまな事情があるがここで語るべきではない。
 
-ocamlmktop, ocamlmklib ★★★
-================================
-まだ書いてない
+リンク支援: ocamlmktop, ocamlmklib ★★
+=================================================
+ocamlmktop および ocamlmklib は外部Cライブラリをリンクした toplevel や
+ライブラリを作成する際に補助的に使用するツールである。
 
-ocamldoc ★★
-=======================
-まだ書いてないよく知らない
+これらのライブラリや toplevel は
+OCaml コンパイラ、C コンパイラ、リンカ、アーカイバ を自分で呼び出すことで
+作成できるのだが、この煩雑な作業を代行してくれるのが
+ocamlmktop と ocamlmklib である。
 
-ocamlbuild ★★★
-======================
-まだ書いてないよく知らない
+プログラムビルドシステム: ocamlbuild ★★★★
+===============================================
+プログラムビルドシステム。
+
+ocamlbuild は簡単な OCaml ソースに対しては ソースファイル名を列挙するだけでモジュール間の依存関係解析からコンパイル、リンクに至るまでを自動的に行なってくれる。そのため Makefile のような既存の外部ビルドシステムにおけるビルドの煩雑さから解放される。
+
+複雑なソース、プログラムコードの自動生成や特殊なリンクが必要な場合など、の場合は myocamlbuild.ml という OCaml モジュールで特殊ルールを実装することができる。myocamlbuild.ml では ocamlbuild が提供するビルドルール記述のためのライブラリを使用することができる。問題はこのライブラリを使うドキュメントがあまり整備されていないこと。(Camlp4 3.10以降系といい、 ocamlbuild といい 3.10 周りで作られたツールはドキュメントが全くなっていない) また、ルール記述が OCaml という汎用言語で書かねばならないためどう見ても書きにくい読みにくいことである。もちろん OCaml の利点である型安全性やパターンマッチ、高階関数などによってビルドルールを構成的に書くことができるのだが…ビルドに特化した Makefile や OMakefile などの文法からするととても読みにくい。もう少し文法拡張などして DSL の風味を付け加えるべきではなかろうか。
+
+私は ocamlbuild は使わない。OMake を使っている。とは言え、どうやら世の中的には ocamlbuild が標準になりつつあるのでそろそろ手を出さねばならない…
+
+ドキュメントシステム: ocamldoc ★★
+======================================
+OCaml のコードを HTML や LaTeX の形に抽出するためのドキュメントシステム。
+``(** ... *)`` という特殊なドキュメントコメントを使うことで簡単な整形記法や
+コード要素に明示的に結び付けられたドキュメントを簡単に書くことができる。
+
+OCaml の標準ライブラリリファレンスドキュメントも ocamldoc によって
+各 \*.mli ファイルから自動的に生成されている。
+(逆に言えば、ライブラリリファレンスをブラウザでアクセスせずとも \*.mli を
+読めば同じ情報が手に入る。)
 
 エディタ支援
 ==================================
 
 caml-types.el は caml.el と独立しており、 tuareg-mode と一緒に使うこともできる。
 
+VIM ユーザは ocaml-annot ( https://github.com/avsm/ocaml-annot ) などを使っているようである。
+
 caml-debug.el ★★
 ----------------------
 ocamldebug を Emacs で使うための elisp。現在実行中のソースコードの場所などを Emacs 中に表示できる。
 ocamldebug を使うためには各バイトコードオブジェクトファイル \*.cmo を 
 ocamlc にデバッグフラグ -g を付けてコンパイルする必要がある。
 
-ocamldebug では一旦進めたデバッグステップを巻き戻すことができるという、ちょっと変わった機能がある。とは言え… printf デバッグか、 gdb を使った native code プログラムのデバッグの方が判りやすい場合が多い。どうしてもプログラム挙動がわからない場合、念のために使われることが多い。これは ocamldebug が非力だからというのではなく、やはり静的に型付けされた関数型プログラムではキャストの誤りや NULL エラーが起こることがなく、あまりデバッグを必要としないからというのが大きい。
+ocamldebug では一旦進めたデバッグステップを巻き戻すことができるという、ちょっと変わった機能がある。とは言え… printf デバッグか、 gdb を使った native code プログラムのデバッグの方が判りやすい場合が多い。どうしてもプログラム挙動がわからない場合、念のために使われることが多い。これは ocamldebug が非力だからというのではなく、やはり静的に型付けされた関数型プログラムではキャストの誤りや NULL エラーが起こることがなく、あまりデバッグを必要としないから、というのが大きい。
 
 バイトコードプロファイラ ocamlprof と ocamlcp ★
 ---------------------------------------------------------
 これを ocamlprof コマンドを使って関数などの使用回数を抽出、
 元のソースファイル内にコメントとして書きだす。
 
-ocamlprof は呼び出された回数しかプロファイルしないので利用されない。
+ocamlprof は呼び出された回数しかプロファイルしないのでほとんど利用されない。
 
-OCaml プログラムでプロファイルを取る場合は、通常
+OCaml プログラムで真面目にプロファイルを取る場合は、通常
 ocamlopt に -p オプションを付けて native code でのプロファイルを取り、
 そのアプトプットを gprof で可視化するのが普通である。
 
 マニアックなツール
 ==================
 
-expunge 
---------
+ディレクトリ名がついている場合、それはインストールされないツールである。 OCaml をビルドするとその場所に実行ファイルができる。
 
+./expunge
+    ライブラリ中のモジュールを外部から見えなくするためのツール。A というモジュールがライブラリにリンクされていれば、このライブラリを使うと外部から A という名前でこのモジュールにアクセスすることができる。 A を expunge すると、それができなくなる。
 ocamlobjinfo
----------------
+    オブジェクトファイルやライブラリ \*.cm\* ファイルの環境依存情報を見ることができる
+tools/dumpobj
+    \*.cmo ファイルをダンプして VM opcode を眺めることができる
+tools/read_cmt
+    OCaml 4.00.0 より -bin-annot オプションにより生成されるバイナリアノテーションファイル \*.cmt をダンプしたり、 \*.annot ファイルに変換することのできるツール。まあ ocamlspot を使えってこった