On Lisp復習
自分用
4章あたり
リストは効率が悪いからか,Lispではパフォーマンスもある程度意識してプログラミングされていくみたい。
ただ,とりあえず最初は単純なものを作れと書かれている。
リストの長さを比較する関数。
length関数で長さを取ると無駄な計算が生じるとのことで。
andとorの使い方がかっこいい。
CL-USER 3 > (defun longer (x y) (labels ((compare (x y) (and (consp x) (or (null y) (compare (cdr x) (cdr y)) )))) (if (and (listp x) (listp y)) (compare x y) (> (length x) (length y)) ))) LONGER CL-USER 4 > (longer '(1 2 3 4) '(1 2 3)) T
filterの高速版と単純版。
CL-USER 5 > (defun filter (fn lst) (let (acc result) (dolist (x lst) (when (setq result (funcall fn x)) (push result acc) )) (nreverse acc) )) FILTER CL-USER 6 > (filter #'(lambda (x) (when (evenp x) (* x 10)) ) '(1 2 3 4 5 6 7 8) ) (20 40 60 80) CL-USER 7 > (defun filter2 (fn lst) (delete nil (mapcar fn lst)) ) FILTER2 CL-USER 9 > (filter2 #'(lambda (x) (when (evenp x) (* x 10)) ) '(1 2 3 4 5 6 7 8) ) (20 40 60 80)
groupの簡易版
CL-USER 1 > (defun group (lst n) (if (endp lst) nil (let ((rest (nthcdr n lst))) (cons (if (consp rest) (subseq lst 0 n) lst) (group rest n) )))) GROUP CL-USER 2 > (group '(1 1 1 1 1 1 1 1 1) 2) ((1 1) (1 1) (1 1) (1 1) (1))
末尾再帰を利用した高速版は眠いので省略。
以上のコードは記憶を頼りに書いたので(本当に覚えてるかの復習目的(だけど数箇所チラチラ見ちゃった。。。))書籍と完全一致してない部分もあるはず・・・。