『初めての人のための LISP [増補改訂版]』

竹内郁雄先生の本『初めての人のための LISP [増補改訂版]』を読んだ.
実は,増補が出る以前から読みたくて,復刊ドットコム で要望を出していたら,本当に再版された.
(あまり,あてにしていなかったけど,復刊ドットコム ってスゴいな.)


内容は,題にもあるように,プログラミング言語 LISP の入門書で,対話的に話が進んでいく.
ちゃんと順番に進んでいくが,大学院で受けた竹内先生の授業と同様に,話がたびたび逸れていってしまう.
なので,最近,周りで話題に出る「話のスタックが浅い人」はついていくのが大変かもしれない.



読む前には,「初めて」といってもこれは入門書じゃないといった意見を聞いていたけれど,そんな感じは受けなかった.
それは,自分が知っている内容が多かったからかもしれないので,ぜひ大学の授業とかで使ってほしいなぁ.
(SICP もそうだけど,LISP 系の言語はやっぱり入門に向いていると思うのだけど,そういう日本の大学はないのだろうか...)
なんといっても,それは置いておいて的な説明が潔く明示されているところが,よくある入門書より目立ったような気がする.これが対話的な入門書のいいところかもしれない.

こんな感じで,『初めての○○』って書いていただきたいなぁ.
例えば,Haskell だったらどうなるんだろう.


本文中で印象に残ったのは,授業のレポートにもあったけど,リストを平らにする irekotori を書けというところ.(授業では flatten と呼んでいたけれど.)
難しいところは,ただ出来ればいいのではなくて,cons,car,cdr の回数が少なければ少ないほどよいというもの.
なので,append とか使ってしまうと,cons が無駄になってしまうので,だめ.
(当然,cons の回数は結果としてできるリストの長さ分ですね.)
結局,当時は答えを教えてくれなかったので,自分の過去のレポートを読みなおしてみた.
提出したのは,以下の関数(Scheme).
(define (flatten x)
    (define (iter x result)
        (cond
            ((null? x) result)
            ((pair? x) (iter (car x) (iter (cdr x) result)))
            (else (cons x result))))
    (iter x '()))

本に出ているものは,以下のもの(Common Lisp).
(defun irekotori (x)
    (cond
        ((null x) x)
        (t (ireko-2 (car x) (irekotori (cdr x))))))
(defun ireko-2 (x y)
    (cond
        ((null x) y)
        ((not (consp x)) (cons x y))
        ((null (cdr x)) (ireko-2 (car x) y))
        (t (ireko-2 (car x) (ireko-2 (cdr x) y)))))

比較してみると,
  '((a b (c d) (e (f (g h) i) j k) l m (n o (p (q)))))
について,

                (car cdr cons)
irekotori:   (25 41 17)
flatten:      (25 25 17)

irekotori は cond の 3 つめの分岐で cdr を呼んでいる分だけ損している訳か.
(あっているのかなぁ..もっと効率良くできますかねぇ?)



あと,本文で一番気になったのは,多くの部分で,「開きガッコ」と「閉じガッコ」と書いてあるところ.
「カッコ」ではない!! なのに,「カッコ」と言っている箇所があったりする.文章に厳しい竹内先生のことなので,どういう使い分けなんだろう.


そういえば,嬉しいことに,研究室の先輩が代理で,竹内先生のサインをもらってきてくださった.


「なんで代理なんだ」とおっしゃっていたらしいが,さすがに僕なんかが会いに行くのもなんか気が引けるなぁ.
ただ,僕の事を覚えていらっしゃったそうなので,いつか挨拶に行きたい.
どのタイミングがいいのだろうか.やっぱりプロシンか.



コメント