dolist
spec で指定したリストの回数だけbodyをループするマクロ
spec には head に指定した変数に tail に続くリストを順番に割り当ててループする。
code: subr.el
(defmacro dolist (spec &rest body)
"Loop over a list.
Evaluate BODY with VAR bound to each car from LIST, in turn.
Then evaluate RESULT to get return value, default nil.
\(fn (VAR LIST RESULT) BODY...)" (declare (indent 1) (debug ((symbolp form &optional form) body)))
(unless (consp spec)
(signal 'wrong-type-argument (list 'consp spec)))
(unless (<= 2 (length spec) 3)
(signal 'wrong-number-of-arguments (list '(2 . 3) (length spec))))
;; It would be cleaner to create an uninterned symbol,
;; but that uses a lot more space when many functions in many files
;; use dolist.
;; FIXME: This cost disappears in byte-compiled lexical-binding files.
(let ((temp '--dolist-tail--))
;; This test does not matter much because both semantics are acceptable,
;; but one is slightly faster with dynamic scoping and the other is
;; slightly faster (and has cleaner semantics) with lexical scoping.
(if lexical-binding
`(let ((,temp ,(nth 1 spec)))
(while ,temp
(let ((,(car spec) (car ,temp)))
,@body
(setq ,temp (cdr ,temp))))
,@(cdr (cdr spec)))
`(let ((,temp ,(nth 1 spec))
,(car spec))
(while ,temp
(setq ,(car spec) (car ,temp))
,@body
(setq ,temp (cdr ,temp)))
,@(if (cdr (cdr spec))
`((setq ,(car spec) nil) ,@(cdr (cdr spec))))))))
code: dolist.el
(dolist (i '(1 2 3))
(message "i: %s" i))