入門Common Lisp

入門Common Lisp―関数型4つの特徴とλ(ラムダ)計算

入門Common Lisp―関数型4つの特徴とλ(ラムダ)計算

(2007-12-23読了)

ここ1年で関数型言語の入門書が増えている.巷ではHaskellもはやっていたらしいけれど,個人的には昔(もう3年前になるのか...)授業でやったLispをきちんと使えるようにしたいということで新納先生の本をチョイス.ここまでシンプルに書かれていると躓かないし,「ほかに何ができるのかな?」という気分になる.いずれにせよ,「これだけで」という本ではないし,「これからプログラミングを始める」本でもない.Rによるクラスタ解析といい,新納先生の本は数学的なスパイスが効いていて個人的には好き.


本書のサブタイトルにある関数型の4つの特徴とは以下のとおり

  1. 式は値を返す
  2. 繰り返しは再帰で書く
  3. 代入式を使わない
  4. 高階関数が使える

それにλ計算が加わる.
式は値を返すというのは,実は今までも使っていたりして,and/orを条件分岐に使うという考え方もこれに則っている.

FILE *fp;
((fp = fopen("hoge.txt", "r")) != NULL) || quit("Cannot open file");

int quit(char *msg){
  printf("%s\n", msg); exit(1);
}

今考えると,実は3年のときのLispのおかげで「ANDはnilが返るまで評価し続ける」「orはnil以外が返ったら終わり」という考え方がついていたのかも.


再帰については,処理速度が遅くなる(リソースを沢山使う)問題点にも触れ,丁寧に手続き的な方法で書いた場合も紹介されている.章の最後には末尾再帰についても解説されている.これは親切.


代入式を使わない章では参照透過性につきる.Lispではsetqを使えるので純粋な関数型言語ではない.ちなみに代入操作の有無ではプログラム言語の記述能力に差はないらしい.ということは,代入操作をしなくても同じ処理を行うプログラムが書けるということ.
Lispが厳密には関数型言語ではない理由もわかった.

  • letで局所変数使えちゃうから
  • prognで手続き的に書くこともできるから

この章では代入操作を行わないプログラムも紹介されているが,結論は「不必要な代入を行わないことで保守性の高いプログラムになる.でも全く行わないと冗長になったり,可読性の低いものになっちゃう」とのこと.
Haskellは純粋な関数型言語なので,どのようになっているのだろうか?


最後の高階関数は,実はPerlでも高階関数(Higher-order function)が使えるのですんなり入ることができた.そっか,Cだと関数のポインタはつくれるけれど,無名関数が作れないのか.なるほどLarry WallPerlLispから派生していると言っていたけれど,高階関数も対応しているのね.Higher-Order Perlを読むのが楽しみになってきた.


λ計算の章は一回で理解するのは難しい.理解できれば簡単なんだろうけれど,すぐにはアタマに入らなかった.ちゃんと読んでみよう.
キーワード

  • カリー化
  • β変換
  • Church-Rosserの定理
  • 正規化定理


以下,自分用メモ

  • PerlのmapはLispのmapcar
  • 二分法
  • Aリストは通常のハッシュ
  • Pリストは破壊的操作しかできないから?構造体のような使い方できそう