pair とリスト構造 (5/5)


関数型と代入

純粋な関数型プログラミングにおいては、代入操作を用いません。 使うのは、 cons (/list) などの constructor (生成関数) のみです。 これらの生成関数によって、field に初期値をあたえると、 以後 filed の値を代入によって変更はしません。 リスト構造を変化させたい場合は、新たに必要なリスト構造をつくることにします。

例えば、Scheme において、 長さ 2 のリストの要素 x に対して、その逆順のリストが欲しければ、

(define y
   (list (cadr x) (car x)))
とすれば要求するリストを作ることができます(cadr は、cdr のcar の意味)。 この際、 (car x), (cadr x) の実体は何ら変化もせず、 そのコピーをとるわけでもありません。 単に、 (car x), (cadr x) はある pair を指す値であり、 list コマンドにより first, second の束縛値を要素とするリストが作られて y に束縛されているわけです。 このため、 仮に first, second が巨大なデータ構造であっても、 大きな負荷になるわけではありません。

このように純粋に関数型な世界では、 一度データ構造を作ってしまうとその中身を変更しません。 このため、データ構造を自然に共有できますし、 また、 プログラムの最適化にも役立てることが可能です()。

自動メモリ管理 (もしくはゴミ集め)

このようにリストがたくさん作られて、 たくさん使われなくなって行きます。 但し、ユーザは別にいらなくなったメモリ領域を明示的に解放する必要はありません。 システムが自動的に使われなくなった領域をみつけて再利用してくれます。 この様な機構を自動メモリ管理と呼び、 回収操作をゴミ集め: Garbage Collection(GC) と言います。 Scheme を含めて Lisp の仲間は GC つきで動いています。

最近では Java などにもついているので、より身近になったともいえるでしょう。 とはいえ、皆さんが良く使うであろう mule/emacs は Emacs Lisp でかかれていて、 以前から GC (= Garbage Collection) 付きで動いていたわけで、 前から身近だったともいえるでしょう。 ユーザに存在が気付かれるようではよい GC とはいえないので、 mule/emacs の GC は優秀なのかもしれません。 ちなみに、mule/emacs で M-x garbage-collect とすると GC してくれます。


99.10.6/ Tomio KAMADA: kamada@cs.kobe-u.ac.jp