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.