OCaml

Software Foundations の ImpParserがあまりに分からなくてつらいので、コンパイラ方面のページを最近あちこち漁っていた。

llvmというのがよいらしい。

http://peta.okechan.net/blog/llvm%E3%81%AB%E3%82%88%E3%82%8B%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E%E3%81%AE%E5%AE%9F%E8%A3%85

とか読む。
うむ。なんとなく分かる。肝心のllvmが出てくる4章以降はまだ読んでないが。
とにかく、トークンで切って、ASTを構築する。と。


上記の翻訳してくれてあるページはC++によるサンプルだけだが、本家のページには、OCaml版もあった。

http://llvm.org/docs/tutorial/OCamlLangImpl1.html

そのコードがまた全く分からぬ。オンライン演習でMinCamlはやって超基本的な文法くらいは分かってるはずなんだが。

let rec lex = parser
  (* Skip any whitespace. *)
  | [< ' (' ' | '\n' | '\r' | '\t'); stream >] -> lex stream

わっつ? parser? [< ?

camlp4という言語拡張を使ってるらしい。ということが分かったのがまたつい最近。
camlp4というのは、OCamlに含まれてんのか含まれてないのか。コマンド別っぽいけど、最近のマニュアルではOCamlの一部みたいなふうにも読める。(ちゃんと読めてない)


閑話休題


RealWorldOCamlもさわりを読んでみたが、
ふつうのOCaml

# List.map languages ~f:String.length;;

とか

# let log_entry maybe_time message =
    let time =
      match maybe_time with
      | Some x -> x
      | None -> Time.now ()
    in
    Time.to_sec_string time ^ " -- " ^ message

とか分からんとか言われる。

Timeの方は、Timeというモジュールが無いんだからしょうがないんだろうけど、
(時間関連のモジュールがデフォルトで使えないどころかそもそも入ってないってだけでも、ええ?って感じではあるが。素のSchemeもそんな感じだったっけ)
~f:String.length とかはどうも見たかんじパラメータ付き引数ぽい。
基本の言語にない文法を最初に持ってくるのかこの本わ。


とにかく、マクロっぽいもので言語拡張出来るんだと。

Lispとか入門書しか読んでませんが、「アホはマクロ使うな。」と必ず書いてあるので、素直に使ったことありませんし、ろくに理解もしてません。
Cでもきつくきつく戒められたことしか記憶にありません。「マクロ使うな使うな。使うと地獄に落ちる。」

OCaml使いは多分初心者とかアホとかいないのであろう。
幸せな言語であることなのだろう。


ところで、OCamlのCoreを入れるのに、
https://github.com/realworldocaml/book/wiki/Installation-Instructions
に従ったのに、結構なエラーが出て何度も失敗した。くじけずに繰り返し実行することで、なんとかutopが入り、

utop # Time.now();;
- : Time.t = 2014-08-16 23:43:37.516682+09:00             

が実行出来た。めでたしめでたし。
しかし実行速度が遅いな。コンパイルして使うからかもしらんが。