評価
lispは大文字、小文字を区別しない。 S式の[S]は「Symbol」のイニシャル (car '(goo choky pah))は (car (quote (goo choky pah)))とおなじ。 '(1 2) ;(1 2) (quote (1 2)) ;(1 2)で同じこと。つまり、それ自体をシンボルとして扱う。 (car (a (b c d))) ;だとa b c dがなんらかの演算子だと評価される。(Aってなんですか、って聞かれる。Aの演算はない。) (car '(a (b c d))) ;とする。 ;これを実行すると、Aが出力される。 (cdr '(a (b c d))) ;((B C D)) ;二重かっこになることに注意。外側のかっこは、cdrにともなっているリスト、内側は、元から付いてるかっこ。 (cdar '(a (b c d))) ; cdr -> car の順で書きたいのなら、逆順。つまり、cadrになる。 cdr of car ofとなるから。 (cadr '(a (b c d))) ;(B C D) (cddr '(a (b c d))) ;NIL (caadr '(a (b c d))) ;A ;caadrとaが二個連続してるけど、問題ないよ。間違わないでね。 (cdadr '(a (b c d))) ;(C D) (cadddr '(a b c d e)) ;D シングルクオーテーションを間違って引用符'---'とかにしないこと。特に文字列を'するときは間違えやすい。 ((nil) nil) ;car:(nil) cdr:(nil)
atom //原子を評価 アトムのことをシンボルという。 Lispには、シンボル、リストの二種類しかない(?) (関数名 引数1 引数2 ..) car:関数名 cdr:(引数1 引数2 ..) (set 'x '(a b c)) (setq x (a b c)) //x = 1とかと同じ。(代入。) x = x+1とかもありだよね。値は、第二引数、つまり、(a b c)が返される。 (setq x ('a 'b 'c)) とかでももちろんエラーが出るよ。'Aは関数にないというエラー。 (setq a nil) (car a) ;nilと表示されるが、普通はエラーのnil (cdr a) ;nil (list 1 2 3) ;(1 2 3) (list 'a 'b 'c) ;(a b c) (list '(a b c)) ; ((a b c)) (cons (cons 'a nil) (cons 'b nil)) ;(cons '(a) '(b)) ;( (a) b ) (cons 'a (list 'b 'c)) ;(cons 'a '(b c)) ;(a b c) (eq () nil) ;T (eq '() nil) ;T nilはシンボルでもあり、リストでもある。 シンボルは一つ。リストは複数作成可能。
listをかけ算する関数 ;これだと、xがnilのときには1が返される。 (defun listmul (x) (cond ((null x) 1) (t (* (car x) (listmul (cdr x)))) )) ;こうやっても、xがnilのときにはうまくいかない。 (defun listmul (x) (cond ((null (cdr x)) (car x)) (t (* (car x) (listmul (cdr x)))) )) ;これでxがnilの場合でもうまく作動する。 (defun listmul (x) (cond ((null x) (print 'error)) (t (_listmul x)) )) (defun _listmul (x) (cond ((null x) 1) (t (* (car x) (_listmul (cdr x)))) ;(2 3 4 5 ..)のようにリストを作る。 (defun range (m n) (cond ((> m n) nil) (t (cons m (range (1+ m) n))) )) 階乗計算 (defun factorial (n) (cond ((= n 0) 1) ((< n 0) (print 'err)) (t (* n (factorial (1- n)))) )) 2で割り切れる数を除去する (defun del (x) (cond ((null x) nil) ((= (mod (car x) 2) 0) (del (cdr x))) (t (cons (car x) (del (cdr x)))) )) ;割り切れなければ、(cons (car x) (cdr x))
エラトステネスの古い
(defun range (m n) (cond ((> m n) nil) (t (cons m (range (1+ m) n))) )) (defun filter (n x) (cond ((null x) nil) ((= (mod (car x) n) 0) (filter n (cdr x))) (t (cons (car x) (filter n (cdr x)))) )) (defun sieve (x) (cond ((null x) nil) (t (cons (car x) (sieve (filter (car x) (cdr x))))) ))
;最後の要素を取り出す。 (defun last-elem (x) (cond ((null x) nil) ;ここは非効率といえば非効率なので、プログラムを分けてもよい。 ((null (cdr x)) (car x)) (t (last-elem (cdr x))) )) ;n番目の要素をとりだす (defun nth-elem (n x) (cond ((= n 0) (car x)) (t (nth-elem (1- n) (cdr x))) )) ;バージョンアップ版 (defun nth-elem (n x) (cond ((< n 0) nil) ;ここは非効率といえば非効率なので、プログラムを分けてもよい。 ((= n 0) (car x)) (t (nth-elem (1- n) (cdr x))) ))
シンボルの数を数える(nilも含めて (defun func (x) (cond ((null x) 1) (t (atom-c1 x)) )) (defun atom-c1 (x) (cond ((null x) 0) ((atom x) 1) (t (+ (atom-c2 (car x)) (atom-c1 (cdr x)))) )) (defun atom-c2 (x) (cond ((null x) 1) ((atom x) 1) (t (+ (atom-c2 (car x)) (atom-c1 (cdr x)))) )) atom-c1, atom-c2だけだとnilのばあい、0と判定されてしまう。 (この場合、()を1と数えるか、0と数えるかは微妙だが。) ()を1と数えたければ、funcから始める。 left rotate (defun rotate (x) (cond ((null x) nil) (t (append (cdr x) (cons (car x) nil) )) )) ;(a b c d) --> (b c d a) (defun max_element (x) (cond ((null (cdr x)) (car x)) ((< (car x) (setq y (max_element (cdr x)))) y) (t (car x)) ))