back

���ޤޤ˽񤭻��餫�������ҡ�

���:

Gauche �桼����ե����

GNU Emacs Lisp Reference Manual

CL manual


fold (�ꥹ�Ȥξ��߹���)

Scheme �ιⳬ�ؿ� fold ��Ƶ��Ǽ������Ƥߤ褦��kons ��2�����δؿ��Ȥ���knil �Ͻ���͡�ls �ϥꥹ�ȤǤ��롣 �ꥹ�Ȥγ����Ǥ� e1,e2,e3...en �Ȥ���ȡ���ü������ e1 ������ knil �� kons �������˺������ˤȤ�줿���Ǥ�����Ū�� kons ���ƹԤ�(���߹���ǹԤ�)��fold �ϼ��η�̤��֤���

(kons en (kons �� (kons e3 (kons e2 (kons e1 knil))) �� ))

fold-right �ϡ���ü������ en ������ knil �� kons �������˱������ˤȤ�줿���Ǥ�����Ū�� kons ���ƹԤ���

(kons e1 (kons e2 (kons e3 �� (kons en knil) �� )))

foldl �μ���(�����Υꥹ�Ȥ�1��)

(defun foldl (kons knil ls)
  (if (null ls)
      knil
    (foldl kons (funcall kons (car ls) knil) (cdr ls))))

(foldl 'cons nil '(1 2 3))
=>(3 2 1)

;; trace
1 -> foldl: kons=cons knil=nil ls=(1 2 3)
| 2 -> foldl: kons=cons knil=(1) ls=(2 3)
| | 3 -> foldl: kons=cons knil=(2 1) ls=(3)
| | | 4 -> foldl: kons=cons knil=(3 2 1) ls=nil
| | | 4 <- foldl: (3 2 1)
| | 3 <- foldl: (3 2 1)
| 2 <- foldl: (3 2 1)
1 <- foldl: (3 2 1)

foldr �μ���(�����Υꥹ�Ȥ�1��)

(defun foldr (kons knil ls)
  (if (null ls)
      knil
    (funcall kons (car ls) (foldr kons knil (cdr ls)))))

(foldr 'cons nil '(1 2 3))
=>(1 2 3)

;; trace
1 -> foldr: kons=cons knil=nil ls=(1 2 3)
| 2 -> foldr: kons=cons knil=nil ls=(2 3)
| | 3 -> foldr: kons=cons knil=nil ls=(3)
| | | 4 -> foldr: kons=cons knil=nil ls=nil
| | | 4 <- foldr: nil
| | 3 <- foldr: (3)
| 2 <- foldr: (2 3)
1 <- foldr: (1 2 3)

foldr �κƵ������ˤ��������Τ�ʤ������ͤޤǤ�Ʊ���褦�ʺƵ��ץ�������é��ⳬ�ؿ���ͤ��Ƥߤ롣�ꥹ�Ȥα�¦����ؿ���Ŭ�Ѥ��ƹԤ��Τ�̾���� mapc-right �Ȥ��������δؿ�����������Ū�ʤΤǡ�kons �Τ褦���֤��ͤ�Ž���碌��Ҥ��ʤ���

(defun mapc-right (func ls)
  (unless (null ls)
    (mapc-right func (cdr ls))
    (funcall func (car ls))))

(mapc-right 'insert '("a" "b" "c"))
cba
=>nil

;; trace
1 -> mapc-right: func=insert ls=("a" "b" "c")
| 2 -> mapc-right: func=insert ls=("b" "c")
| | 3 -> mapc-right: func=insert ls=("c")
| | | 4 -> mapc-right: func=insert ls=nil
| | | 4 <- mapc-right: nil
| | 3 <- mapc-right: nil
| 2 <- mapc-right: nil
1 <- mapc-right: nil
;; ����
(mapc 'insert '("a" "b" "c"))
abc
=>("a" "b" "c")

fold �����

(foldl '+ 0 '(1 2 3 4 5 6 7 8 9 10))
=>55

(foldl '* 1 '(1 2 3 4 5 6 7 8 9 10))
=>3628800

;; reverse
(foldl 'cons nil '(1 2 3 4 5 6 7 8 9 10))
=>(10 9 8 7 6 5 4 3 2 1)

;; �ս�˽���
(foldr (lambda (x k) (princ x (current-buffer))) nil '(1 2 3))
321

fold (ȿ��)

���ä����Ƶ��� fold ��������Ƥ� Emacs Lisp �ǤϺƵ����Ȥ�����̤ϸ¤��롣�ѿ� max-lisp-eval-depth �ǺƵ��ο��������¤���Ƥ��롣�����ƤӽФ�����Ŭ������뤳�Ȥ�ʤ�������Ǥ� fold �ϻȤ��ʤ���ȿ����ʸ��Ȥä� fold ���ľ������

foldl �μ���(�����Υꥹ�Ȥ�1��)

;; cl-do 1
(defun foldl (kons knil ls)
  (do ((ls ls (cdr ls))
       (knil knil (funcall kons (car ls) knil)))
      ((null ls) knil)))
;; cl-do 2
(defun foldl (kons knil ls)
  (do ((ls ls (cdr ls)))
      ((null ls) knil)
    (setq knil (funcall kons (car ls) knil))))
;; while
(defun foldl (kons knil ls)
  (while ls
    (setq knil (funcall kons (car ls) knil))
    (pop ls))
  knil)
;; dolist
(defun foldl (kons knil ls)
  (dolist (x ls knil)
    (setq knil (funcall kons x knil))))
;; mapc
(defun foldl (kons knil ls)
  (mapc (lambda (x) (setq knil (funcall kons x knil))) ls)
  knil)

foldr ���

(defun foldr (kons knil ls)
  (foldl kons knil (reverse ls)))

iota

Scheme �� iota �ؿ���Ƶ���������Ƥߤ褦��

(defun iota (count &optional start step)
  (let ((start (or start 0))
        (step (or step 1)))
    (if (<= count 0)
        nil
      (cons start (iota (- count 1) (+ start step) step)))))

CL �� defun* ��Ȥ��С����ץ���ʥ�����˥ǥե�����ͤ���ꤹ�뤳�Ȥ��Ǥ��롣

(defun* iota (count &optional (start 0) (step 1))
  (if (<= count 0)
      nil
    (cons start (iota (- count 1) (+ start step) step))))
;; cl-labels
(defun* iota (count &optional (start 0) (step 1))
  (labels ((rec (count start)
             (if (= count 0)
                 nil
               (cons start (rec (- count 1) (+ start step))))))
    (rec count start)))

���3�ĤϺƵ��ʤΤ� Emacs �ǤϻȤ��ʤ��������å������С��ե�����ȯ���������˥��顼�ǻߤޤäƤ��ޤ���max-lisp-eval-depth �ν���ͤ� 300 �Ǥ��롣

(iota 100)
Debugger entered--Lisp error: (error "Lisp nesting exceeds `max-lisp-eval-depth'")

ȿ����ʸ��ȤäƤ����Ĥ��񤤤Ƥߤ���

;; while
(defun iota (count &optional start step)
  (let ((start (or start 0))
        (step (or step 1))
        (result nil))
    (while (> count 0)
      (setq result (cons start result)
            start (+ start step)
            count (- count 1)))
    (nreverse result)))
;; dotimes
(defun iota (count &optional start step)
  (let ((start (or start 0))
        (step (or step 1))
        (ans nil))
    (dotimes (x count (nreverse ans))
      (push start ans)
      (setq start (+ start step)))))
;; cl-do
(defun* iota (count &optional (start 0) (step 1))
  (do ((count count (- count 1))
       (start start (+ start step))
       (acc nil (cons start acc)))
      ((<= count 0) (nreverse acc))))
;; foldl
(defun* iota (count &optional (start 0) (step 1))
  (nreverse
   (foldl (lambda (x k) (cons (+ (car k) step) k))
          (list start)
          (make-list (- count 1) nil))))

Scheme �� SLIB ���������Ƥ����Ρ�list-tabulate ��ȤäƤ��롣

(defun list-tabulate (len proc)
  (do ((i (- len 1) (- i 1))
       (ans '() (cons (funcall proc i) ans)))
      ((< i 0) ans)))

(defun iota (count &rest args)
  (let ((start (if (null args) 0 (car args)))
        (step (if (or (null args) (null (cdr args))) 1 (cadr args))))
    (list-tabulate count (lambda (idx) (+ start (* step idx))))))
(list-tabulate 10 (lambda (i) (sqrt (1+ i))))
=>(1.0 1.4142135623730951 1.7320508075688772 2.0 2.23606797749979 ...)

factorial (����)

�����׻�����Ƶ��ؿ� factorial �ϼ��Τ褦�ʤ�Τ���Emacs Lisp �Ǥ�ư��롣

(defun factorial (n)
  (if (= n 1)
      1
    (* n (factorial (- n 1)))))

��������Emacs Lisp �ξ�硢�Ƶ������¤����˰������������ϰϤ�Ķ���Ƥ��ޤ��Τǡ�11�γ���ޤǤ����׻��Ǥ��ʤ��ä���12�γ���� 479001600 �ˤʤ�ʤ��Ȥ����ʤ���

(factorial 11)
=>39916800

(factorial 12)
=>-57869312

29�ӥåȤ�2�������κ����ͤ�10�ʤ�268435455�ˤʤ롣�����1��­����-268435456�ˤʤꡢ�ޥ˥奢��ˤ��Ф��줬 Emacs �ΰ����������κǾ����ϰϤǤ��롣(GNU Emacs 22.1.1)

;; ������
(1- (expt 2 28))
=>268435455

#b01111111111111111111111111111
=>268435455

(foldl (lambda (x k) (+ (expt 2 x) k)) 0 (iota 28 0))
=>268435455

;; �Ǿ���
(expt 2 28)
=>-268435456

#b10000000000000000000000000000
=>-268435456

(1+ (foldl (lambda (x k) (+ (expt 2 x) k)) 0 (iota 28 0)))
=>-268435456

const (������֤��ؿ����֤�)

(defun const (x) (lexical-let ((x x)) (lambda (i) x)))

(defun const (x) `(lambda (i) ,x))

(list-tabulate 10 (const 1))
=>(1 1 1 1 1 1 1 1 1 1)

compose (�ؿ��ι���)

���Τ� f �� g �ι����ؿ����֤���f �� g ��1�����ؿ��ǡ��֤��줿�ؿ���1�����ؿ���

(defun compose (f g)
  (lexical-let ((f f) (g g))
    (lambda (x) (funcall f (funcall g x)))))

(defun compose (f g)
  `(lambda (x) (funcall #',f (funcall #',g x))))

(defun compose (f g)
  `(lambda (x) (funcall (function ,f) (funcall (function ,g) x))))

(list-tabulate 10 (compose 'sqrt '1+))
=>(1.0 1.4142135623730951 1.7320508075688772 2.0 2.23606797749979 ...)

���٤ϡ�On Lisp ���������Ƥ��� compose �� foldr �Ǽ������Ƥߤ�������ϡ��Ǹ�δؿ��ʳ���1�����ؿ���Ǥ�դο��δؿ�������Ǥ��롣�֤��ͤδؿ��ΰ����ϺǸ�δؿ��ΰ�����Ʊ����

(defun compose (&rest fns)
  (if fns
      (lexical-let ((fns fns))
        (lambda (&rest args)
          (foldr #'funcall (apply (car (last fns)) args) (butlast fns))))
    #'identity))

���ˡ�compose ��Ȥä� complement ��������Ƥߤ롣

(defun complement (pred)
  (compose #'not pred))

(mapcar (complement 'evenp) '(1 2 3))       ;=> (t nil t)
(mapcar* (complement '=) '(1 2 3) '(1 1 3)) ;=> (nil t nil)

any-pred

Scheme �� any-pred ��������Ƥߤ���

(defun any-pred (&rest pred)
  (lexical-let ((pred pred))
    (lambda (&rest args)
      (block nil
        (mapc (lambda (f)
                (let ((r (apply f args)))
                  (and r (return r))))
              pred)
        nil))))
(fset 'string-or-symbol? (any-pred 'stringp 'symbolp))

(string-or-symbol? "abc")                 ;=>t
(string-or-symbol? 'abc)                  ;=>t
(string-or-symbol? 3)                     ;=>nil

(fset '<> (any-pred '< '>))

(<> 3 4)                            ;=>t
(<> 3 3)                            ;=>nil

(funcall (any-pred (lambda (x) (memq x '(a b c)))
                   (lambda (x) (memq x '(1 2 3))))
         'b)
=>(b c)

every-pred

Ʊ���� every-pred ��

(defun every-pred (&rest pred)
  (lexical-let ((pred pred))
    (lambda (&rest args)
      (block nil
        (let (ans)
          (mapc (lambda (f)
                  (or (setq ans (apply f args))
                      (return ans)))
                pred)
          ans)))))
(defun positive? (x) (> x 0))
(defun negative? (x) (< x 0))
(funcall (every-pred 'oddp 'positive?) 3)  ;=> t
(funcall (every-pred 'oddp 'positive?) 4)  ;=> nil
(funcall (every-pred 'oddp 'positive?) -3) ;=>nil

(fset 'my-safe-length (every-pred 'listp 'length)) ;safe-length �� Emacs �ˤ��롣
(my-safe-length '(a b c))                 ;=> 3
(my-safe-length "aaa")                    ;=> nil

and=>

���뼰��ɾ��������̤����ΤȤ��ˤ����������ͤ�ȤäƲ��餫�ν����򤷤�����礬���롣Emacs Lisp �Ǥϡ�ɾ���ͤǶɽ��ѿ���«�����Ƥ����ơ��������«���ѿ���Ȥä�ʬ��������񤯤��Ȥˤʤ�Ȼפ�����������scheme �ʤ� cond �����Ȥ��롣

(cond (expr => func))

Emacs Lisp �ξ�硣

(let ((var expr))
  (and var
       (funcall func var)))

�ޥ�����񤤤Ƥߤ���expr ��ɾ���ͤ����ξ��*�Τ�*�������ͤ� func ��Ƥ����̤� and=> ��ɾ���ͤȤʤ롣expr ���ͤ� nil �ʤ� nil ���֤���

(defmacro and=> (expr func)
  (let ((var (make-symbol "var")))
    `(let ((,var ,expr))
       (and ,var (funcall ,func ,var)))))
(and=> t (const 1))                ;=> 1
(and=> nil (const 1))              ;=> nil

and=> ��Ȥä� any-pred ��

(defun any-pred (&rest pred)
  (lexical-let ((pred pred))
    (lambda (&rest args)
      (block nil
        (mapc (lambda (f)
                (and=> (apply f args) (lambda (r) (return r))))
              pred)
        nil))))

let=>

and=> �ϼ���ɾ���ͤ�ؿ����Ϥ��������� let=> �ʤɤ�ͤ�����Ȼפ����ѿ� var �� expr ��ɾ���ͤ�«�����ơ����ξ��*�Τ�* body ��ɾ�����롣

(defmacro let=> (var expr &rest body)
  `(let ((,var ,expr))
     (when ,var
       ,@body)))

let=> ��Ȥä� any-pred ��

(defun any-pred (&rest pred)
  (lexical-let ((pred pred))
    (lambda (&rest args)
      (block nil
        (mapc (lambda (f) (let=> r (apply f args) (return r)))
              pred)
        nil))))

for-each

Scheme �� for-each �� Emacs Lisp �� mapc �Τ褦����������Ū�ǻȤ��ؿ������������Υꥹ�Ȥ�ʣ���Ȥ뤳�Ȥ��Ǥ��롣TSPL ���������Ƥ����Τ� Emacs Lisp �ǽ񤤤Ƥߤ���

(defun for-each (f ls &rest more)
  (do ((ls ls (cdr ls)) (more more (mapcar #'cdr more)))
      ((null ls))
    (apply f (car ls) (mapcar #'car more))))

�¹���

(let ((same-count 0))
  (for-each
   (lambda (x y)
     (if (= x y)
         (setq same-count (+ same-count 1))))
   '(1 2 3 4 5 6)
   '(2 3 3 4 7 6))
  same-count)
=>3

��������� mapcar ��ư���Ϥä���ȥ��᡼��������ɤ�����Ǥ��롣

(for-each (compose 'print '+) '(1 2 3) '(4 5 6) '(7 8 9))
12
15
18

ls = (1 2 3) : more = ((4 5 6) (7 8 9)) ;ls = ls       : more  = more
(apply f 1 (4 7))                       ;1  = (car ls) : (4 7) = (mapcar 'car more)
(f 1 4 7) =>12

ls = (2 3) : more = ((5 6) (8 9))       ;ls = (cdr ls) : more  = (mapcar 'cdr more)
(apply f 2 (5 8))                       ;2  = (car ls) : (5 8) = (mapcar 'car more)
(f 2 5 8) =>15

ls = (3) : more = ((6) (9))             ;ls = (cdr ls) : more  = (mapcar 'cdr more)
(apply f 3 (6 9))                       ;3  = (car ls) : (6 9) = (mapcar 'car more)
(f 3 6 9) =>18

map

���٤� map ��������Ƥߤ褦���ޤ��ϰ����Υꥹ�Ȥ�1�ĤκƵ��ǡ�

(defun map1 (f ls)
  (if (null ls)
      '()
    (cons (funcall f (car ls)) (map1 f (cdr ls)))))

(map1 (lambda (x) (* x x)) '(1 2 3))  ;=>(1 4 9)

ȿ����ʸ��ȤäƤ��ñ�˼����Ǥ��롣

(defun map1 (f ls)
  (do ((ls ls (cdr ls))
       (a nil (cons (funcall f (car ls)) a)))
      ((null ls) (nreverse a))))

(defun map1 (f ls)
  (let (a)
    (while ls
      (push (funcall f (car ls)) a)
      (pop ls))
    (nreverse a)))

(defun map1 (f ls)
  (let (a)
    (dolist (x ls (nreverse a))
      (push (funcall f x) a))))

ʣ���Υꥹ�Ȥ�Ȥ� map �ϡ��ؿ���Ŭ�Ѥ�����̤�ꥹ�Ȥ˽����Ф褤�Τǡ�for-each ��������餹�������Ǥ��롣CL ��Ʊ̾�δؿ�������Τǡ�̾���� map* �Ȥ�����

(defun map* (f ls &rest more)
  (do ((ls ls (cdr ls)) (more more (mapcar #'cdr more))
       (a nil (cons (apply f (car ls) (mapcar #'car more)) a)))
      ((null ls) (nreverse a))))

�¹���

(map* 'car '((a b) (c d) (e f)))                       ;=>(a c e)
(map* 'cadr '((a b) (c d) (e f)))                      ;=>(b d f)
(map* 'cons '(a b c) '(d e f))                         ;=>((a . d) (b . e) (c . f))
(map* '+ '(1 2 3) '(4 5 6) '(7 8 9))                   ;=>(12 15 18)

fold (�ꥹ�Ȥξ��߹���) 2

�����Υꥹ�Ȥ�ʣ���Ȥ뤳�Ȥ��Ǥ��� fold ��������褦��for-each �� map �Ȼ�����������Ǥ��ʤ����������ȹͤ�����knil �� kons ���ʤ������Ѥ��ƹԤ��Ȥ���������Ǻ����������γƥꥹ�Ȥ�Ĺ����Ʊ���Ǥ���Ȥ��롣

(defun fold (kons knil ls &rest more)
  (do ((ls ls (cdr ls)) (more more (mapcar #'cdr more))
       (knil knil (apply
                   kons
                   (apply #'list (car ls) (append (mapcar #'car more) (list knil))))))
      ((null ls) knil)))

quasiquote, unquote, unquote-splicing ��Ȥ��Ф��ä���񤱤롣

(defun fold (kons knil ls &rest more)
  (do ((ls ls (cdr ls)) (more more (mapcar #'cdr more))
       (knil knil (apply kons `(,(car ls) ,@(mapcar #'car more) ,knil))))
      ((null ls) knil)))

�¹���

(fold 'cons '() '(1 2 3))               ;=>(3 2 1)
(fold 'list '() '(1 2 3) '(4 5 6))      ;=>(3 6 (2 5 (1 4 nil)))
(fold '+ 0 '(1 2 3) '(4 5 6) '(7 8 9))  ;=>45
(fold 'acons '() '(1 2 3) '(4 5 6))     ;=>((3 . 6) (2 . 5) (1 . 4))

���� fold-right ���������ᡢapply ��Ȥ����Ȥ��פ��⤫�Ф�������Ǻ�����

(defun fold-right (kons knil ls &rest more)
  (apply #'fold kons knil (reverse ls) (mapcar #'reverse more)))

�¹���

(fold-right 'cons '() '(a b c d e))           ;=>(a b c d e)
(fold-right 'list '() '(1 2 3) '(4 5 6))      ;=>(1 4 (2 5 (3 6 nil)))
(fold-right '+ 0 '(1 2 3) '(4 5 6) '(7 8 9))  ;=>45
(fold-right 'acons '() '(1 2 3) '(4 5 6))     ;=>((1 . 4) (2 . 5) (3 . 6))

�ʾ������ǡ�mapcar �����������Ѥߤ� map* ��ȤäƤ��꤯�Ԥ���


let1

Gauche �� let1 ���ȤƤ���������Emacs Lisp �Ǥ�Ȥ�������

(defmacro let1 (var expr &rest body)
  `(let ((,var ,expr))
     ,@body))

let �� lambda ���ǽ񤱤�ΤǼ��Τ褦�ˤ�����Ǥ��롣

(defmacro let1 (var expr &rest body)
  `((lambda (,var) ,@body) ,expr))

circular-list

�۴ĥꥹ�Ȥ��ۤ��� circular-list ��������Ƥߤ���1�İʾ�Υ��֥������Ȥ�����ˤȤ롣

(defun circular-list (obj &rest args)
  (let1 cl (cons obj args)
    (setcdr (last cl) cl)
    cl))
(let1 cl (circular-list 1 2 3 4 5)
  cl)
=>(1 2 3 4 5 1 2 3 4 . #4)

(let1 cl (circular-list 1 2 3 4 5)
  (nth 9 cl))
=>5

�۴ĥꥹ�Ȥ��ɤ�����Ĵ�٤� circular-list-p �����������

(defun circular-list-p (ls)
  (do ((fast (cddr ls) (cddr fast))
       (slow (cdr ls) (cdr slow)))
      ((null fast))
    (and (equal fast slow) (return t))))
(let1 cl (apply 'circular-list (iota 10))
  (circular-list-p cl))
=>t

(let1 cl (iota 10)
  (circular-list-p cl))
=>nil

filter

filter �ϡ��ꥹ�Ȥ� pred ��Ŭ�Ѥ�����̡������֤����Ǥ򽸤�롣

(defun filter (pred ls)
  (if (null ls)
      nil
    (let1 o (car ls)
      (if (funcall pred o)
          (cons o (filter pred (cdr ls)))
        (filter pred (cdr ls))))))

(defun filter (pred ls)
  (do ((ls ls (cdr ls))
       (a nil (let1 o (car ls)
                (if (funcall pred o) (cons o a) a))))
      ((null ls) (nreverse a))))

(defun filter (pred ls)
  (let (a)
    (while ls
      (let1 o (car ls)
        (when (funcall pred o) (push o a)))
      (pop ls))
    (nreverse a)))

(defun filter (pred ls)
  (let (a)
    (dolist (x ls (nreverse a))
      (and (funcall pred x) (push x a)))))
(filter 'evenp (iota 10))
=>(0 2 4 6 8)

append-map

append-map �� map �η�̤�ʿó�����롣����Ѥߤ� map* �� CL �� mapcar* ��Ȥ�(CL �� mapcan ��Ʊ���褦�ʤ�Ρ�)��SICP �Ǥϡ�flatmap �Ȥ����������Ƥ��롣Haskell �� OCaml �Ǥ� concatMap �Ȥ����餷����

(defun append-map (f ls &rest more)
  (apply 'append (apply 'map* f ls more)))

fringe

append-map ��Ȥäơ�fringe ��������롣fringe �ϡ������Ȥ����ڤ�Ȥꡢ�ڤΤ��٤Ƥ����Ǥ򺸤��鱦�ν���¤٤��ꥹ�Ȥ��֤�(SICP Exercise 2.28)��

(defun fringe (tree)
  (if (listp tree)
      (append-map 'fringe tree)
    (list tree)))

count-leaves

count-leaves (SICP Exercise 2.35) ���ڤΡ��դο��򤹤٤ƿ����롣����Ѥߤ� fold ��Ȥä���

(defun count-leaves (tree)
  (foldl (lambda (x y)
	  (if (consp x)
	      (+ (count-leaves x) y)
	    (+ 1 y)))
	0
	tree))

(defun count-leaves (tree)
  (foldl '+
	 0
	 (mapcar (lambda (s)
		   (if (consp s)
		       (count-leaves s)
		     1))
		 tree)))

count

count �����������CL ��Ʊ̾�δؿ�������Τ� count* �Ȥ�����

(defun count* (pred ls &rest more)
  (let* ((x (cons ls more))
	 (n (apply 'min (mapcar 'length (cons ls more)))))
    (do ((n n (- n 1))
	 (x x (mapcar 'cdr x))
	 (ans 0 (if (apply pred (mapcar 'car x)) (+ ans 1) ans)))
	((= n 0) ans))))

�ؿ�̾���ѹ�

Emacs Lisp �Ǥ�̾�����֤���ͭ�����Τǡ��ؿ�̾�˥ץ�ե��å������դ���̾�����ˡ����ˤ���Τ������������̤ˡ��ץ�ե��å����ȻĤ�Υ���ܥ�� `-' ��ʬ����Τ�����`-' ���Ǥ��ˤ����Τǡ�`:' ��ʬ���� Scheme �� `s' �ΰ�ʸ����ץ�ե��å����ˤ��뤳�Ȥˤ���(����ѥ������Ÿ�������ޥ����Ϥ��Τޤޤˤ���)��CL �δؿ�̾�Ⱦ��ͤ���Τ��򤱤뤿����դ��� `*' ���뤳�Ȥˤ������������äơ�count* ���ä��� s:count �ˤʤ롣

count �Ǥϡ���Ϳ����줿�ꥹ�ȤΤ����Ǥ�û���ꥹ�ȡפȤ������ͤ��������褦�������������¾�δؿ����碌�ƽ������롣


filter-map

filter-map �ϡ�filter �� map ���Ȥ߹�碌����Ρ����ˤʤ���η�̤򽸤�롣

(defun s:filter-map (f ls &rest more)
  (let* ((x (cons ls more))
	 (n (apply 'min (mapcar 'length x))))
    (do ((n n (- n 1))
	 (x x (mapcar 'cdr x))
	 (ans nil (let1 r (apply f (mapcar 'car x))
		    (if r (cons r ans) ans))))
	((= n 0) (nreverse ans)))))
(s:filter-map (lambda (x) (and (numberp x) (* x x)))
	      '(a 1 b 3 c 7))
=>(1 9 49)

take / drop / split-at

take �� drop �� split-at �����������

(defun s:take (x i)
  (do ((i (- i 1) (- i 1)) (x x (cdr x))
       (ans nil (cons (car x) ans)))
      ((or (< i 0) (null x)) (nreverse ans))))
(defun s:drop (x i) (nthcdr i x))
(defun s:split-at (x i)
  (if (or (> i (length x))
	  (< i 0))
      (error "Given list is too short: %S" x)
    (list (s:take x i) (s:drop x i))))
(s:take '(a b c d e) 2)       => (a b)

(s:drop '(a b c d e) 2)       => (c d e)

(s:split-at '(a b c d e) 2)   => ((a b) (c d e))

find / list-index / last

find �� list-index �� last �����������find �� pred �������֤��ǽ�����Ǥ��֤���

(defun s:find (pred ls)
  (do ((ls ls (if (funcall pred (car ls))
		  (return (car ls))
		(cdr ls))))
      ((null ls) nil)))
(defun s:list-index (pred ls)
  (do ((i 0 (+ i 1))
       (ls ls (if (funcall pred (car ls))
		  (return i)
		(cdr ls))))
      ((null ls) nil)))
(defun s:last (ls) (car (last ls)))

partition

partition �����������

(defun s:partition (pred ls)
  (do ((ls ls (cdr ls))
       (drop nil)
       (take nil (if (funcall pred (car ls))
		     (cons (car ls) take)
		   (push (car ls) drop)
		   take)))
      ((null ls) (list (nreverse take) (nreverse drop)))))
(s:partition 'oddp '(3 1 4 5 9 2 6))	=>((3 1 5 9) (4 2 6))

take-while / drop-while

take-while �� drop-while �����������

(defun s:take-while (pred ls)
  (do ((ls ls (cdr ls))
       (ans nil (if (funcall pred (car ls))
		    (cons (car ls) ans)
		  (return (nreverse ans)))))
      ((null ls) (nreverse ans))))
(defun s:drop-while (pred ls)
  (do ((ls ls (if (funcall pred (car ls))
		  (cdr ls)
		(return ls))))
      ((null ls) ls)))

any / every

any �� every �����������

(defun s:any (pred ls &rest more)
  (let* ((x (cons ls more))
	 (n (apply 'min (mapcar 'length x))))
    (do ((n n (- n 1))
	 (x x (mapcar 'cdr x))
	 (ans (apply pred (mapcar 'car x))
	      (apply pred (mapcar 'car x))))
	((= n 0) ans)
      (when ans (return ans)))))
(defun s:every (pred ls &rest more)
  (let* ((x (cons ls more))
	 (n (apply 'min (mapcar 'length x))))
    (do ((n n (- n 1))
	 (x x (mapcar 'cdr x))
	 (ans (apply pred (mapcar 'car x))
	      (apply pred (mapcar 'car x))))
	((= n 0) ans)
      (unless ans (return nil)))))

Last modified: Thu Mar 20 04:50:22 JST 2008
Copyright (C) 2008 Kazushi NODA All Right Reserved.

Valid HTML 4.01 Transitional Valid CSS