Common Lisp Tips

Lisper達の情報を共有する場所

参考URL

分からないことがあったら、ここを覗くといいかも

関数

関数を定義するときは defun (DEfine FUNction) を使います。

自作した関数を公開する場所(誰かが改良してくれるかも)

  • リストのn番目に要素を追加する
(defun add-to-ls (item ls n)
   (cond ((<= n 1) (cons item ls))
         ((null ls) (cons item nil))
         (t (cons (car ls) (add-to-ls item (cdr ls) (- n 1))))))
末尾呼び出しver
(add-to-ls (item lst n &optional (head '()))
      (cond
 ((<= n 1) (nconc (nreverse head) (list item) lst))
 ((null lst) (nconc (nreverse head) (list item)))
 (t (add-to-ls item (cdr lst) (1- n) (cons (car lst) head))))))

いろんな等しさの述語

  • eq 「同じオブジェクトか?」アドレスを比較しているらしい。動作は処理系依存。
  • eql 「同じオブジェクトか?」eqとの違いは処理系に依存しないところ(シンボルとアトムの違いとする情報もあるけどよくわかりません)。
  • = 「同じ数(number)か?」
  • equal 2つのリストは等しいか?、調べるときに使ったりする。
  • equalp 2つのベクトルは等しいか?、を調べられる1番大雑把な等しさの述語

集合に関する関数

1つのリストを1つの集合として見る。 ls1='(1 2 3 4), ls2='(3 4 5 6)とする。

  • 和:(union ls1 ls2)->(1 2 3 4 5 6);;順番は保証されない
  • 差:(set-difference ls1 ls2)->(1 2);;順番は保証されない
  • 積:(intersection ls1 ls2)->(3 4);;順番は保証されない
  • 排他的論理和:(set-exclusive-or ls1 ls2)->(1 2 5 6);;順番は保証されない
  • 重複しない場合に追加(非破壊):(adjoin 5 ls1)->(5 1 2 3 4),(adjoin 4 ls1)->(1 2 3 4)
  • 重複しない場合に追加(破壊):(pushnew 5 ls1)->(5 1 2 3 4)
  • 先頭から何番目?:(position 2 ls1)->1
  • 何個あるか?:(count 1 '(1 1 2 1 2 3 1 2 3 4))->4
  • 列の部分コピー:(subseq ls1 1 3)->(2 3)

doとdo*

doとdo*はどちらも繰り返しの構文。

どちらも下記の形式

(do ((変数名 初期値 step-form)...)
    (test 返り値)
    body)
  • 初期値で変数を束縛
  • testが真であれば返り値を返し、偽であればbodyを評価、step-formの評価値で新たに変数を束縛
  • testが真であれば繰り返しを終了し、偽であれば繰り返す。

doとdo*でstep-formの評価順?が異なる。

 (do ((temp-one 1 (1+ temp-one))
      (temp-two 0 (1+ temp-one)))     
     ((= 3 temp-two) temp-one)) =>  3

 (do* ((temp-one 1 (1+ temp-one))
       (temp-two 0 (1+ temp-one)))
      ((= 3 temp-two) temp-one)) => 2
  • doは全てのtest-formを一斉に評価(前回の変数の値を見る)
  • do*は上のtest-formから順に評価(最新の変数の値を見る)

上記の例での変数の値の移り変わり

  • do
    • temp-one 1->2->3
    • temp-two 0->2->3
  • do*
    • temp-one 1->2
    • temp-one 0->3
Last modified:2018/04/11 15:15:35
Keyword(s):
References:[プログラミング]