今、私はもう一度自己宣伝に行きます:Pしかし、私が途中でいくつかの有用な情報を伝えることを期待して:
;; Here is what `dolist' expands to:
(dolist (item listy)
(messager item))
(identity
(catch (quote --cl-block-nil--)
(let ((--dolist-tail-- listy) item)
(while --dolist-tail--
(setq item (car --dolist-tail--))
(messager item)
(setq --dolist-tail-- (cdr --dolist-tail--))))))
;; And here is what `i-iterate' expands to:
(++ (for item in listy)
(messager item))
(let* ((--0 listy) item)
(while --0
(setq item (car --0) --0 (cdr --0))
(messager item)))
いくつかの解説:条件付き出口があるかどうかに関係なくブロックdolist
を作成しますが、そのような条件付き出口が識別された場合にのみそれを試みます。一般に、フォーム内でのコードの実行は少し遅くなります。(catch ...)
i-iterate
(catch ...)
また、dolist
コードを特別な「ブロック」(基本的にはidentity
関数の呼び出しにすぎません。これも一種のくだらないものであり、デフォルトですが、常に必要なわけではありません)にラップします。
さて、についての他の質問に対して、次のようなマクロalist
を使用できます。loop
(loop for (key . value) in '((a . b) (c . d)) do
(message "key: %s -> value: %s" key value))
;; Which expands to:
(identity
(catch (quote --cl-block-nil--)
(let* ((--cl-var-- (quote ((a . b) (c . d)))) (value nil) (key nil))
(while (consp --cl-var--)
(setq value (car --cl-var--)
key (car (prog1 value (setq value (cdr value)))))
(message "key: %s -> value: %s" key value)
(setq --cl-var-- (cdr --cl-var--))) nil)))
;; Compared to i-iterate
(++ (for (key . value) in '((a . b) (c . d)))
(message "key: %s -> value: %s" key value))
;; Which expands to:
(let* ((--0 (quote ((a . b) (c . d)))) value key)
(while --0
(setq key (caar --0) value (cdar --0) --0 (cdr --0))
(message "key: %s -> value: %s" key value)))
ここで、この特定のケースでは、使用pop
は正当化されませんでした。同様に、(catch ...)
ブロックの使用(条件付きの終了がなかったため)。
ああ、そしてライブラリへのリンク:http ://code.google.com/p/i-iterate/ :)
この目的で使用することの利点と欠点mapc
:高階関数は、既存の関数とうまく組み合わされます。したがって、すべての要素に適用したいものがすでにある場合は、おそらくそれが問題を解決するための最良の方法です。ただし、高階関数でのみ使用する関数を作成する場合は、他の方法では回避できた「冗長」インスタンスを作成するため、効果が得られることはめったにありません。常にそうであるとは限りません。特にマクロで使用する場合、これは強力なツールになることがありますが、あなたの場合と同様に、反復の方が適しているようです。