lispの練習
Lispはデータもリスト処理も区別せず,全く同じルールで計算する.
QUOTEのやくわり
'apple
はフォームだが,これをひょうかするとappleというデータとなる.
関数の引数はデータ型であると分かって初めてその関数を適用できる.
(+ a x)
(list '(1 2)) ;与えられた引数を要素としてリストを作る. (append '(a b) '(c d)) ;(A B C D) (list '(a b) '(c d)) ;((A B) (C D)) (format t "The age of my ~A is ~A" pet age) ;pet age は変数 (while 条件式 式 式 …) (loop 式 式 式 …) (loop (and (> x 100) (return sum)) (setq sum (+ sum x)) (setq x (+ 1 x)) ) ;List 1 : dotimes の例 (defun fact (x) (let ((result 1)) (dotimes (n x result) (setq result (* result (1+ n)))))) ;List 2 : 要素の個数を求める(dolist 版) (defun my-length (x) (let ((result 0)) (dolist (y x result) (setq result (1+ result))))) (if <条件節> (progn S式A S式B ... ) ; then 節 (progn S式a S式b ... )) ; else 節 ;図 6 : if と progn の組み合わせ ;if の then 節や else 節は複数の S 式を受け付けません。このような場合、progn を使えば複数の S 式を評価することができます。 ;prog1 は最初に評価した S 式の値が返り値となります。prog2 は 2 番目に評価した S 式の値が返り値となります。
┌─┬─┐ ┌─┬─┐ │・│・┼─→ nil │・│・┼─→ b └┼┴─┘ └┼┴─┘ ↓ ↓ a a (a) ≡ (a . nil) (a . b) ┌─┬─┐ ┌─┬─┐ ┌─┬─┐ │・│・┼─→│・│・┼─→│・│・┼─→nil └┼┴─┘ └┼┴─┘ └┼┴─┘ ↓ ↓ ↓ a b c (a b c) ≡ (a . (b . (c . nil)))
Lispのデータ構造は階層的になっている.NILは,リストでもあり,アトムでもあるという決まりになっている. シンボルは,関数名,変数名,関数でも変数でもないデータのこと. 文字列とシンボルの違いは シンボルは唯一存在するもの(計算機のメモリ内の同じ場所にある)だが, 文字列はふつう,メモリ内の違う場所にある. (t e a m) == "team" と思ってもらってよい. その考え方でいくと,一見同じ字面のリストでも記憶先の場所が違う. 例えば, '(I like lisp) と '(I like lisp) は違うメモリ内にある.
;= は,二つの数が等しい場合に真を返す (= 3 3.0) t (= 3 9/3) t ;eq は同一のオブジェクト (つまりアドレスが等しい) 場合に真を返す。(二つのシンボルが等しいかどうか) (eq 'im 'im) t ;シンボルとして等しい (eq 3 3) t (eq "im" "im") nil (eq 3.0 3) nil (eq '(a b c) '(a b c)) nil ;eql は eq を満たしている、あるいは、同じ型で同じ値の数値や、同じ値の文字であれば真を返す。 (eql 'im 'im) t (eql "im" "im") nil (eql '(a b c) '(a b c)) nil (eql 3.0 3) nil ;(注意)eq と eqlの違いは (eq 3.0 3.0) nil (eql 3.0 3.0) t ;だけ. ;'='は同じ数かどうかを調べるのに使う ;'eq'は同じシンボルかどうかを調べるのに使う. ;'eql'は同じシンボルか,または同じ数かどうかを調べるのに使う. ;equal は eql を満たしている、あるいは、equal を満たすリストや内容が等しい文字列であれば真を返す。(二つのリストが同じか否か) (equal '(he she they) '(he she they)) t (equal 3 3.0) nil (equal "Robert" "Robert") t ;equalp は equal を満たしている、あるいは、型が違っても同じ値の数値、 ;文字や文字列では英大小文字を区別しない、equalp を満たすリストや配列であれば真を返す。 ;等しいと判定される範囲が eq < eql < equal < equalp と広がっていきます。
;バッククォートは基本的にはクォートと変わらない。 'x ;=> x `x ;=> x '(a b c) ;=> (a b c) `(a b c) ;=> (a b c) ;ただし、リストに対して用いられた場合、カンマ(,)を用いることでクオートの効果を打ち消すことができる。 ;バッククォート中で,@に続くものがリストであるとき、リストは周囲の要素と同じレベルにつなぎ込まれる。 (setq x '(2 3)) `(1 ,@x 4) ;=> (1 2 3 4)
;' stops evaluation ;#' produces procedure objects from procedure names. ;defun stores procedure descriptions away as procedure objects.