OCamlで"Hello, World!"を出力する

はじめに

Rustを学んでいると、どうしても型安全性を理解したくなり、積ん読していた「型システム入門*1」を読み始めました。気長に読み進めていくと思います。

型システム入門 −プログラミング言語と型の理論−

型システム入門 −プログラミング言語と型の理論−

  • 作者:Benjamin C. Pierce
  • 発売日: 2013/03/26
  • メディア: 単行本(ソフトカバー)

この本ではOCamlという関数型プログラミング言語が使われていますので、今回はOCamlをとりあえず使ってみたよという記事です。

プログラミング言語

OCamlは初めて触ります。少しだけプログラミング言語とは?という素朴な疑問に立ち返りたいと思います。プログラミング言語では何かしらの計算をします。つまり計算というものを記述できるのがプログラミング言語です。

プログラミング言語と計算モデル

計算を扱う理論分野では数学的に研究するために計算というものをモデリングします。そのようにして表されたものを計算モデルと呼びます。

C言語など命令形プログラミング言語は状態を変化させながら計算をするオートマトンという計算モデルが背景にあります。そしてHaskellOCamlなど関数型プログラミング言語においてはラムダ計算という計算モデルが背景となっています。他には一階述語論理という計算モデルが背景にあるPrologなど論理型プログラミング言語もあります。

背景とされる理論によってプログラミング言語の設計が変わります。その設計によってプログラミングパラダイムというプログラミングの考え方やスタイルのようなものが決まります。実際のプログラミング言語はいくつかのプログラミングパラダイムが組み合わさったりしています。

OCaml

OCaml (Objective Caml)は関数型のプログラミング言語の1つです。そしてMeta-Language (以下MLと略記)という関数型プログラミング言語の方言です。さらにOCamlはMLの方言であるCamlオブジェクト指向プログラミングという別のプログラミングパラダイムを合わせた言語でもあります。

ちなみにMLの標準仕様、もしくは方言の1つという位置づけにはStandard MLというものもあります*2

Hello, World!

OCamlで"Hello, World!"を出力します。

インストール方法は公式のサイトを参照ください。私はVimを使っているのでVimでOCamlを書くためにmerlinとocp-indentを設定するを参考にエディタの設定をしました。

インタプリタ

OCamlインタプリタもありますので、まずはそちらを使って"Hello, World!"していきたいと思います。文字列の出力はprint_stringを使います。

$ ocaml
        OCaml version 4.10.0

# print_string "Hello, World!";;
Hello, World!- : unit = ()

出力できました。unitはデータ型の1つで()という値のみを持ちます。

実行ファイル

main.mlというファイルに以下を記述します。

print_endline "Hello, World!"

print_endlineは改行付きで与えた文字列を表示します。コンパイルして実行します。

$ ocamlc main.ml
$ ./a.out
Hello, World!

表示できました。

関数を使う

関数定義にはfunfunctionという2つのキーワードを使う方法があります。

funは次のような感じです。

let hello = fun () -> print_endline "Hello, World!";;

functionは次のようになります。

let hello = function () -> print_endline "Hello, World!";;

同じように見えますが、funと違いfunctionはパターンマッチングです。例えば以下のようなことができます。

let hello = function
    i when i = 0 -> print_endline "i = 0"
  | i when i > 0  -> print_endline "i > 0"
  | i when i < 0 -> print_endline "i < 0"
  | _ -> assert false;;

これをコンパイルして実行すると次のようになりました。

$ ./a.out
i < 0
i = 0
i > 0

funの書き換え

funキーワードを使った関数定義は別の書き方ができます。

まずはfunを使った"Hello, World!"を載せます。引数に与えた文字列を出力します。

let hello = fun s -> print_endline s;;
hello  "Hello, World!";;

これを実行すると以下のようになります。

$ ocamlc main.ml
$ ./a.out
Hello, World!

書き換えですが、funキーワードを使わずに以下のように書けます。

let hello s = print_endline s;;
hello "Hello, World!";;

ざっとネットを見る感じ、こちらの書き方の方が使われていそうです*3

おわりに

最終的にできた"Hello World"をgkuga/ocaml-examplesに置きました。

exception Exit of int

let main () = print_endline "Hello, World!"

let res =
  Printexc.print (fun () ->
      try
        main ();
        0
      with
        Exit x -> x
    ) ()

let () = exit res

Printexc.printでは補足できなかった例外を画面に出力します。上記の例では使う意味はないのですが、とりあえず使ってみました。

参考

ググって面白そうなサイトを自分の備忘録として載せておきます。TaPL本をわかりたい。

*1:TaPL本と言われているようです

*2:LispCommon Lispみたいな感じでしょうか?

*3:なんででしょう?文字数を少なくできるから?