Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2009-12-12

KMRCLを眺める (37) REMOVE-FROM-TREE-IF

| 21:13 | KMRCLを眺める (37) REMOVE-FROM-TREE-IF - わだばLisperになる を含むブックマーク はてなブックマーク - KMRCLを眺める (37) REMOVE-FROM-TREE-IF - わだばLisperになる

今回は、KMRCLのlists.lisp中からREMOVE-FROM-TREE-IFです。

定義は

(defun remove-from-tree-if (pred tree &optional atom-processor)
  "Strip from tree of atoms that satistify predicate"
  (if (atom tree)
      (unless (funcall pred tree)
        (if atom-processor
            (funcall atom-processor tree)
          tree))
    (let ((car-strip (remove-from-tree-if pred (car tree) atom-processor))
          (cdr-strip (remove-from-tree-if pred (cdr tree) atom-processor)))
      (cond
       ((and car-strip (atom (cadr tree)) (null cdr-strip))
        (list car-strip))
       ((and car-strip cdr-strip)
        (cons car-strip cdr-strip))
       (car-strip
        car-strip)
       (cdr-strip
        cdr-strip)))))

動作は、名前からすると、REMOVE-IFのtree版というところですが、

(DEFVAR *TREE* '(1 A 2 B 3 C 4 D () () (5 E 6 F 7 G (8 9 10) 11 12) 13))

(REMOVE-FROM-TREE-IF #'VALUES *TREE*)
;⇒ NIL

(REMOVE-FROM-TREE-IF #'NULL *TREE*)
;=> (1 A 2 B 3 C 4 D (5 E 6 F 7 G (8 9 10) 11 12) 13)

(REMOVE-FROM-TREE-IF (LAMBDA (X)
                       (IF (SYMBOLP X)
                           X
                           (EVENP X)))
                     *TREE*)
;⇒ (1 3 (5 7 (9) 11) 13)

(REMOVE-FROM-TREE-IF #'SYMBOLP
                     *TREE*
                     (LAMBDA (N) (AND (ODDP N) N)))
;⇒ (1 3 (5 7 (9) 11) 13)

(REMOVE-FROM-TREE-IF #'NUMBERP *TREE*)
;⇒ (A B C D (E F . G))

なんだかちょっと素直じゃないような気も。

再帰する部分が何度も出てくるので、LETの束縛部分に書いてありますが、自分も好きで長くなくても良くこう書きます。

それと、瑣末なところですが、REMOVE-FROM-TREE-IFの定義に使われているIFのインデント方式は読み辛いです…