OCaml入門の手引

OCamlを学ぶには、まず何から手を付けたらいいでしょうか? あなたなら何をしますか?

私はこれまで、恐らく10数回はOCamlを覚えようとしました。そして手を付けては諦め、また付けては諦めの繰り返しで、ついには数えるのをやめてしまったくらいです。

でも、今回は続いています。ひょっとすると、コミュニティそのものに何か根本的な変化があったのかもしれません。

私にとって功を奏したのが実際は何だったのか、以下に考察してみたいと思います。

役に立つ本は?

Real World OCaml(以下、RWO)』がお勧めです。というよりも、それ以外にお勧めはありません。RWOは、私の生涯の中でも1、2を争うことができるくらいのコンピュータ言語解説書です。

ちなみに、その他にも解説書はありますが、大体が不正確な内容を含んでいるか、あるいはフランス語で書かれているかなので、読まない方がいいでしょう。

(編集:ある論評では、『OCaml from the Very Beginning』はそれほど悪くなく、より初心者向きと評されています。私自身は読んだことはありませんが、Yaron Minksy氏もこの本に対していい印象を持っているようなので、一見の価値はあるかもしれません。)

以下が、私の感じたRWOの優れた点です。

  • よくまとめられており、説得力があります。
  • HTMLで作成され、オンラインで公開されています。これはつまり:(1)本を買わなくてもいい、そして(2)コード部分を直接コピー&ペーストできる、ということです。
  • 言語の重要な機能のほとんど全てに対して、使用の妥当性が明確に提示されています。
    • 「使用の妥当性」をもう少し具体的に説明すると、生産システムにおける機能の妥当な使用法ついて、著者が十分な知識を提供しているということです。
    • そのいい例に、パターンマッチングについて書かれた箇所を挙げることができます。この内容によると、マッチングでコンピュータプログラム(またその仕様)のソースコードがより厳密に構文化され、有限状態マシンになると言います。そのため、仮に2つのパターンがオーバーラップした場合、1つのパターンのチェックというよりも、巧みにネストされた多くのif文を通り抜けるようなチェックになり、それと完全に同じチェックが、次のパターンに対しても常に繰り返されるというわけです。このような内容は、生産コードを書く上で、この種の直感的な知識が欲しい私のような人間にとっては非常にためになるものです。
    • 多くの本では、例えばコアの抽象化(例:ここがforループです)やコアライブラリ(例:これを呼び出してListを取得します)を説明する時に、順を追って説明するだけですが、RWOはそうではなく、その背景にある情報まで説明してくれます。
  • ランタイムについて1つの章が割かれています。章全体にわたってですよ!
    • 「ランタイム」とは、プログラム実行中に動いているもの全てを指します。もちろんGCや並行性制御なども例外ではありません。
    • これは本当に重要なことです。なぜなら、もし生産言語のランタイムがどのように作用するかについて知識を得られる環境にない場合、あなたは巨大なリスクを負っていることになるからです。それにもかかわらず、ランタイムに大きくページを割いている言語の本はほとんどありません。
    • この章を通して、こういったリスクを管理するのに必要な数多くの知識を得ることができます。本当に目からウロコでOCamlに対する私の態度は180度変わりました。以前なら、OCamlを生産の現場に持ち込もうなんて思いもしませんでしたが、今となっては、リスクが少ないということが理解できる気がしています。
    • 例えばこの本を、私の愛してやまない『Learn You A Haskell』と比べてみましょう。『Learn You A Haskell』はとても面白いですし、私に(モナドなどの)重要なことを教えてくれました。ただし、言語がどのように実行されるかということについてはほとんど触れられていません。これは非常に重大な欠点と言わざるを得ないでしょう。結果的にHaskellは、私にとって暇つぶしのおもちゃのようなものになってしまったのです。
  • 重要なタスクを解決するためのツールについて1つの章が丸ごと割かれています。これには、構文解析と字句解析、シリアライゼーション、並列ライブラリなども含まれています。
  • (言うまでもありませんが、この他には、言語、機能、コアAPIについての章があります。)
  • ひどい標準ライブラリやツールは無視しましょう。この本では、Jane Street CapitalとOCaml Labsによってまとめられた非常に優れたツールチェーンを中心に話が展開します。標準ライブラリや標準ツール(例:パッケージマネージャ)は一様にひどいもので、RWO以前には、それらがOCamlの学習に際して、大きな障害となっていました。新しいツールチェーンは、適切に文書化されている上にサポートも十分で、本当にすばらしいものです。そのためRWOでは、標準ライブラリやツールの代わりに、このツールチェーンを中心としています。

どんなツールを使うべきか?

OCamlは非常に強力な型システムです。この事実に加えて、型が通常、推論される(すなわち、通常は明示的に記述されない)という事実を考慮すると、OCamlは、最終的にうまくいくまで、正しいと直感したことを何度も試す言語であると考えることができます。

でも、お願いです。

どうか気楽に考えてください。

コンパイラが入力した記述を誤りだと指摘する可能性を、少しでも軽減できるツールに投資しましょう。

RWOのインストール手順最後まで従ってください。特に:

  • utopをインストール(OCaml REPL)。これを使って試行錯誤を繰り返し、コードの実行によってあなたの直感の正否を確認します。
  • OPAM(OCamlパッケージマネージャ)をインストール。これは言うまでもありませんね。以前はOCamlのバージョンを切り替えたり単純なライブラリをインストールしたりするだけでも一苦労でした。OPAMを使うと、それらの苦労が解消されますし、他言語と比べても使い勝手はかなりいい方だと思います。
  • エディタツール。とにかく使いましょう。EmacsとVimの両方で動作するTuaregやMerlinは必要です。EmacsやVimは使っていないですか? それなら今後、OCamlに対してはEmacsやVimを使うようにしてください。これらのツールとエディタを使うと、ツールなしで他のエディタを使うよりも、はるかに効率が上がります。

ツールに投資するには時間や労力が必要になってきますよね。そこで、少しでもその気になってもらえそうな例を以下に示します。

ファイルは保存時にコンパイルされます。そして、コンパイルされていないものは黄色で表示されます。

入力すると、Merlinがオートコンプリートのリストを表示します。

Merlinにはホットキーの機能があり(EmacsではC-cTAB)、それを使ってオートコンプリートのリストを呼び出すことも可能です。

もう1つのホットキー(EmacsではC-c C-t)によって、カーソルが今置かれている箇所の式の型が分かります!(画面の下部に表示されます)これを使えばコンパイラに型エラーを指摘されることがないので、すごく便利です。

型を示す式の上で同じ組み合わせのキーを押すと、単に型の定義が表示されます!

できることがたくさんあります。これはほんの一部です。任意のものですが、実際にかなり時間の節約になります

手本として参照できるソースは?

いい質問です! 熟練プログラマのOCamlらしい使い方を参考にするのは重要です!

最高のオープンOCamlシステムは恐らくJane Street CoreJane Street Core Kernelです。例えば、マップの実装は非常に優れています。

OCaml Labsから生まれたutopなどのソースは優れていますが、残念ながら、優れたオープンソースのOCamlプロジェクトを一般的に入手するのはまだ少し困難です。恐らくいつかは改善されるでしょう。

役に立つチュートリアルは?

現在は、素晴らしいOCamlの標準チュートリアルがあります。以前は存在すらしておらず、その後提供されたのは質が低いものでした。しかし今は素晴らしくなっています。

99のOCaml問題の演習はまあまあです。あなたの持つ知識によっては最善の学習方法ではないかもしれませんが、私にとっては標準的なOCamlデータ構造の一般的な操作を学ぶのに有用な方法でした。特に、何かコードを書いて解決策を検討することによって、OCamlらしく書けていない箇所が分かるので、役に立ちました。

OCamlの公式の”学習”ページには両方が含まれています。学び始めにはとてもいいリソースですし、今後も定期的に更新されるでしょう。

役に立つドキュメントは?

手始めはCore.Stdのドキュメントがいいでしょう。Jane Street Coreの標準的なデータ構造が説明されているので、始めるのにピッタリです。

始めるにあたっては、オンライン上のRWOの関連する章に目を通す必要があるかもしれません(実際、私には必要でした)。

相談相手は?

IRCは好評のようですし、メーリングリストもあると聞いています。ただ、私は相談する友人がいるので、どちらも使っていません。

初級者へのお勧めは?

進め方はみんな違いますが、私は次のような方法でうまくいきました。

  • 経験のレベルに応じたアプリケーションを実装することから始めてください。私は、Boggleゲームを解くプログラム、コマンドラインパーサ、正規表現パーサ、それにいくつか機械学習の問題に取り組みました。もっと簡単なものを選ぶか難しいものにするかはあなた次第です。
  • エディタを使って頻繁に式の型をチェックしてください。コンパイルエラーによるフラストレーションを軽減できます。エディタの保存時にコンパイル機能を使ってコンパイルするかどうかチェックしてください。エディタを使ってインタラクティブに型チェックを行う方法はエディタを使わない方法よりも高速です。
  • 私は、何かコードを書く前に、型とそのインターフェースの概略を書き出すことから始めるのが非常に有効だと思いました。ただ、人によって違うかもしれません。
  • 他の言語で行いたいこと全てをOCamlでも実現する方法を見つけるようにしてください。例えば、Pythonのリスト内包表記はモナドのbindの特別なケースです。すてきですね! 全てを実現できれば、もっと快適にOCamlを使えるようになるでしょう。考えをコードに置き換えることによって信頼に値する確固たる何かを得られるからです。
  • 必要に応じて多くのソースを読んでください。私にとってはOCamlの慣用句を理解するのにJane Street Coreがとても役に立ちました。
  • 99の問題などによって、何かを実装して、それを実行する慣用的な方法を確認できます。これはものすごく役に立ちます。
  • コードレビューをしてもらってください。私にはこれをやってくれる友人がいます。OCamlの規約に合っていない箇所を指摘してもらえるので、すごく助かります。

結論

上記の他に言うことはあまりないと思います。うまくいったことやうまくいかなかったことについて何かあれば、ご意見をお寄せいただければ幸いです。