Previous Up Next
2 Objective Caml 入門

別に配布するテキストを参照のこと.以下は,テキストからの Objective Caml 言語に関する記述の一部抜粋である.

2.1 Objective Caml とは

プログラミング言語 ML は,元々は計算機による証明支援系から発展 してきた言語1 で,関数型プログラミングと呼ばれるプログラミングスタイルをサポートして いる.MLは核となる部分が小さくシンプルであるため,プログラミング初心者 向けの教育用に適した言語である.と同時に,大規模なアプリケーション開発の ためのサポート(モジュールシステム・ライブラリ)が充実している.MLの核言 語は型付きλ計算と呼ばれる,形式的な計算モデルに基づいている. このことは,言語仕様を形式的に(数学的な厳密な概念を用いて)定義し,その 性質を厳密に「証明」することを可能にしている.実際,Standard ML という 言語仕様[4]においては,(コンパイラの受理する)正しいプログラ ムは決して未定義の動作をおこさない,といった性質が証明されている.

この実験及演習で学ぶのは ML の方言である Objective Caml という言語である. Objective Caml は INRIA というフランスの国立の計算機科学の研究所でデザイン・開 発された言語で,Standard ML とは文法的には違った言語であるが,ほとんど の機能は共有している.また,OCaml では Standard ML には見られない,独 自の拡張が多く施されており,関数型プログラミングだけでなく,オブジェク ト指向プログラミングもサポートされている.またコンパイラも効率的なコー ドを生成する優れたものが開発されている.

2.2 Objective Caml 言語の雰囲気

Objective Caml 言語の概要をプログラム例を混じえて紹介する.これは Objective Caml という言語 自体の説明だけでなく,この実験で作成する処理系の動作例にもなっている.
Objective Camlは,いわゆる関数型言語である
計算の仕組みは Scheme に似ていて,式を値に評価することでプログラム実行が進む.例えば,Scheme では,
(define (fact n)
  (if (= n 0) 1 (* n (fact (- n 1)))))
(fact 5)
と入力すると,階乗関数 fact が定義されて,次の式の入力により 120 が返ってくるが,Objective Camlでは以下のように書く.
let rec fact n = 
  if n = 0 then 1 else n * fact (n-1);;
fact 5;;
何となく対応関係がわかるだろうか.

関数も値である
もちろん,Scheme のように,関数を 返す関数や,関数を引数に取る関数なども自由に使える.例えば,以下は 与えられた関数 f と整数 n から ∑i=0n f(i) を計算する関数である.
let rec sum (f, n) =
  if n = 0 then f(n) else f(n) + sum (f, n-1);;
sum (fact, 5);;
とすると,0! + 1! + 2! + 3! + 4! + 5! が計算されて,154 が返ってくる.

Objective Camlには静的型があり,強く型付けされる
Objective Camlプログラムに対して は実行前に型検査が行われ,演算子などの誤った使用がないかどうかが 検査される.型の合わない計算をさせようとすると, 実行をする前に(静的に)エラーが発生して誤りを指摘される.
let hoge x = x + 1 + "hoge";;
などと入力すると,その時点で,hoge を呼び出してもいないのに,
This expression has type string but is here used with type int
つまり,"hoge" という文字列が,+ という整数を期待している演算子の 引数として使われていますよ,という意味のメッセージ(ここではシステムか らの返答を表すために斜体を使っている)とともにコンパイルエラーが発生す る. (実際は "hoge"の下に下線がひかれて, This expression がどれな のかも教えてくれる.)このエラーは, hoge を呼び出して実際に足し算が 行われようとする前に発生するのがミソである.また,Objective Camlでは,型検査 を通過した場合には,文字列と整数の足し算のようなエラーが実行時に発生し ないことが,(数学的に)保証されている.このことを Objective Caml は強 く型付けされた(strongly typed)言語である,という.

Objective Camlは型推論をしてくれる
C言語にも静的型があるが, 関数宣言の際に,仮引数の型を宣言する必要がある.これに対して Objective Camlでは上の例からも見てとれるように,引数の型や返り値の型 をいちいち書かなくても,システムが推論をしてくれる.例えば,
let rec fact n = 
  if n = 0 then 1 else n * fact (n-1);;
とすると,システムからは,
val fact : int -> int = <fun>
という反応が返ってくる.これは fact が整数(int)を受け取って, 整数を返す関数(->)だということを示している.

Objective Camlにはパターンマッチ機能がある


Objective Caml には,パターンマッチという機能があって,リストなど 構造のある値に対して,パターンを当てはめて,値の一部を取りだすこと ができる.Objective Caml では,リストを [] (空リスト),:: (cons) を使って, 1 :: 2 :: 3 :: [] のように書くのだが2,整数リストの先頭2要素までの和を計算 する関数 sum_of_first_two は,パターンマッチを使うと
let sum_of_first_two l =
  match l with
     [] -> 0
   | x :: [] -> x
   | x :: y :: rest -> x + y;;
val sum_of_first_two : int list -> int = <fun>
と書ける. match は関数の引数 l に対して,[] (空リストパターン)や x::[] (1要素パターン) や x::y::rest (2要素以上パターン) を当てはめて, 当てはまったら,変数 x (や y) をリストの要素として,計算を行う.パターンマッチを使うと,条件分岐を複 雑に入れ子にすることなく,全ての場合が一度に書き下せるのが魅力である. ちなみに,型に現れる -> の左側の int listは整数が並んだリスト が引 数としてとれることを示している.

Objective Caml の型は多相的
多相的,というのは,ひとつのプログラムの 型がいろいろ変化することを示している.例えば,以下は,リストの長さを計算する関数であるが,
let rec length list =
  match list with
     [] -> 0
   | x::rest -> 1 + length rest;;
これは,整数のリストに使うこともできるし,文字列のリストに使うこともできる.
length (2::3::4::[]);;
- : int = 3
length ("hoge"::"foo"::"bar"::"baz"::[]);;
- : int = 4
つまり,ひとつの関数 length を,「整数リストを受けとって整数を返す」 関数や「文字列リストを受けとって整数を返す」関数という別の型のものとして 使える.ソーティング関数なども,整数のソーティング,文字列のソーティングなど 異なる種類のデータに対するソーティングを,ひとつの定義で記述することができる. このようなプログラミングを,型が多相的でない C 言語などで(安全性を損なわないで)行うのは難しい.

その他の特徴
Scheme と同様,ごみ集め(garbage collection)により,自動メモリ管理が行われるため,プログラマは C 言語の malloc/free などを使ったメモリ管理のように 頭を悩ませる必要がない.また,対話的にプログラム開発ができるインタラクティブ・コンパイラと, ソースコードを一括して実行形式に変換するバッチ・コンパイラが利用できる.

Previous Up Next