2013年8月28日水曜日

OCamlとRubyで同じプログラムを書いてみた

以前書いたとおり、OCamlRubyで簡単な家計簿プログラムmohを作った。全く同じというわけではなく、後に作ったRuby版のほうが機能を追加したりしているけど、面白い経験だったので感想を書いてみる。

客観的な比較


サイズを行数で比較すると、OCaml版は279、Ruby版は360で、Ruby版の方が機能が増えていることを考えるとほぼ同じくらいといえると思う。ただし、Rubyはユニットテストが作成に不可欠だったので、それを加えると499行とOCaml版に比べて倍くらいになる。まあユニットテストはOCamlでもした方がいいのだろうが、あとで述べる通り、しなくても動いてしまったのでユニットテストはしていない。いずれにしても、どちらも同じくらいコンパクトな言語だといえると思う。

OCamlのいいところ


これからは主観の入った比較となる。

よくOCamlは「コンパイルが通ればバグはないと言わしめる…」という枕詞が付く。もちろん、それは誇張だが、という但し書き付きで。しかし、mohを作ったときは本当にそうで、型検査が通った後のメインのロジックでバグは出なかった。悩まされたバグの原因はすべて正規表現だった。一方で、Rubyで書いたときは何度か型エラーに悩まされた。ユニットテストを書いてはいたが、型エラーが最後の段階、つまり誤ったメソッドが呼ばれるところまで分からないのでデバッグが難しかった。一方で、OCamlの型チェッカは型エラーの原因の比較的近くでエラーを検出するので型エラーではほとんど悩まされなかった。

よくユニットテストをするから型検査は不要、という議論があるけれどそれが間違いであることがわかると思う。一方で、ちゃんとした型システムをもった言語(JavaとかC++ではなく)を使うと実際に信頼性と生産性の向上に役に立つこともわかると思う。mohの開発では結局ユニットテストはしていない。(した方がいいことはわかっている。)

Rubyのいいところ

正直あまり感じなかった…ただ、オブジェクト指向というのは良い点かもしれない。OCaml版のmohでは内部のデータ構造にListを使っているのだけど、これをコードにベタに書いてしまっているのであとで変え難いというにはある。もちろんOCamlでもモジュールに隠蔽すれば簡単に変えられるようになるけれど、モジュールは若干構文が重い感じがする。全体的にOCamlは構文が重い気がする。

あと、正規表現の扱い。OCamlでは正規表現で何度も悩まされた。文字列リテラルでバックスラッシュ「\」をエスケープしなくてはいけないので、正規表現だと2重にエスケープしなくてはいけないことが多く、何がなんだかわからなくなる。これはStrモジュールを使った(Pcreではなく)せいもあるのかもしれないけど。

あと、CSVを解析するモジュールとか、ライブラリはやはり豊富でよく考えられていると思った。

まあまとめると、OCamlは中身、Rubyは見た目とHypeだなあと思いました。