第1講 初めての人のためのLisp
アトム
: これ以上分解できない値
text 100010 アトム -5
第2講 carとcdrで世間を渡れば権兵衛もたじろぐ
空のリスト () を nil と呼ぶ
car : リストの1番目の要素
cdr : car を取り除いた残りのリスト 一番左の括弧を一つ右に下げる リストであることに注意
アトムとリスト(nil も含む)を総称してS式(Symbolic expression)と呼ぶ
atom 関数はアトムの場合 t を返す
(print (atom 1010))
(print (atom "hoge"))
(print (atom (cons 1 0)))-
nil はリストでありアトムでもある
(atom nil) -
null 関数は nil の場合 t を返す
(print (null nil)) (print (null 10)) (print (null (cons 1 0)))
第3講 解釈は評価なり・・・辞書なくして世は渡れず
数を評価したらその数自身になる
以下は同じ意味
(set 'B 'hoge)
(setq B 'hoge)第4講 基本関数を修了するや,突然関数定義,なんと大それた・・・
cons の2番目の引数は(nilでもよいが)リストでなければならない
次のコードに注意
(cons (cons 'A nil) (cons 'B nil))第5講 今度はcond,再帰と再起を混同せぬように・・・
関数風(car に関数名があって、その後ろに引数が並んだリスト)の式で表すけれど、引数の形が得々であったり、引数が評価されないような式は 特殊形式(secial form) と呼ばれる。
Lisp では「…か?」と聞く関数の最後に p をつけるのが慣習。 p は predicate(述語) の頭文字
動詞で「(…だと)断定する」という意味だそうです。
プログラミング全般での使い方は、c#のPredicateのドキュメントがわかりやすかったです。
要は、接頭辞にIsやCanを付けるような、何かを渡してboolを返す関数のことだと理解しました。
cite : 【プログラミング全般】Predicateとは
第6講 またも再帰するから再帰なのだ
累積変数とは 再帰処理でこれまでの結果を次々に溜めるための変数。 reduceで使われるのもそれ。
自分自身を呼び出すことがそのまま最終結果に鳴るような再帰呼出しのことを 末尾再帰 と呼ぶ
末尾再帰でない再帰関数はスタックを累積していくのでスタックオーバーフローを起こす可能性がある。累積変数を使い末尾再帰にしたほうが良い。
参考 : 末尾再帰による最適化
第7講 go,go,go・・・,do,do,do・・・,loop,loop,loop・・・,やっぱりOは丸い
prog の話は現在では使わなそうなのでとりあえずスルー
末尾再帰は簡単に繰り返しに変形できる
(progn 式1 式2 ...式n) は、式1、式2と準に評価していき、最後の式nの値を返す
下記のように複数方向に再帰的に定義されるものは、繰り返しよりも再帰法が効果的である。
(defun cons-count (x)
(cond ((atom x) 0)
(t (+ 1 (cons-count (car x))
(cons-count(cdr x))))))
(cons-count '(hoge (huga hoo) nil hage))第8講 Lisp御本尊のお出まし
セルの cdr 部に nil 以外のアトムが現れない限り、ドット記法を使う必要がない
第9講 デート前にリストの切り貼り
rplaca, rplacd の説明 ひとまず覚えておかなくて良い
第10講 変態プログラム
第11講 シンボルを人前に曝す
第12講 ガールフレンドも買い物も関数引数でOK
高階関数の話。特にメモなし。
第13講 Lispの解剖 その1
リストの第0要素がマクロであった場合は、第1要素以下を評価せずにマクロの本体に渡す。そしてマクロ本体が返してきた値をその場でもう一度評価する。
第14講 入出力がなければプログラムは生きていけぬ
必要な都度、次々に先頭から文字を取り出せるものを ストリーム と呼ぶ
関数で &rest の後ろにある引数は、残りの引数をまとめてリストにして受け取る変数
(defun foo (&rest lst)
(reduce '+ lst)
)
(foo 1 2 3)6
関数で &optional の後ろにある引数は、引数が与えられていない場合デフォルトの値に束縛される
(defun foo (x &optional (y 2) (z (+ x y)))
(+ x y z)
)
(foo 1)6
Common Lisp では名前空間のことを シンボル・パッケージ あるいは パッケージ と呼ぶ
シンボルはどれかのパッケージに属し、Common Lisp では標準で lisp, user, keyword, system の4つが用意されている
関数をキーワード引数を使って定義するには &key を使う
(defun foo (&key (hoge 1) (hage 1))
(+ hoge hage))
(foo :hage 4)5