* lisp/emacs-lisp/seq.el (seq-doseq): Tighten the code

(seq-doseq): Fix out-of-scope binding.
Don't call `seq-length at every iteration.
Reduce `if's from 3 to 2 per iteration.
(emacs-lisp-mode-hook): Don't tweak in Emacs≥25.
This commit is contained in:
Stefan Monnier 2015-04-24 16:11:35 -04:00
parent 18a78f8215
commit e224c9465d
2 changed files with 18 additions and 18 deletions

View file

@ -790,7 +790,7 @@ of type @var{type}. @var{type} can be one of the following symbols:
@end example
@end defun
@defmac seq-doseq (var sequence [result]) body@dots{}
@defmac seq-doseq (var sequence) body@dots{}
@cindex sequence iteration
This macro is like @code{dolist}, except that @var{sequence} can be a list,
vector or string (@pxref{Iteration} for more information about the

View file

@ -44,31 +44,28 @@
(defmacro seq-doseq (spec &rest body)
"Loop over a sequence.
Similar to `dolist' but can be applied lists, strings and vectors.
Similar to `dolist' but can be applied to lists, strings, and vectors.
Evaluate BODY with VAR bound to each element of SEQ, in turn.
Then evaluate RESULT to get return value, default nil.
\(fn (VAR SEQ [RESULT]) BODY...)"
\(fn (VAR SEQ) BODY...)"
(declare (indent 1) (debug ((symbolp form &optional form) body)))
(let ((is-list (make-symbol "is-list"))
(seq (make-symbol "seq"))
(index (make-symbol "index")))
`(let* ((,seq ,(cadr spec))
(,is-list (listp ,seq))
(,length (if (listp ,seq) nil (seq-length ,seq)))
(,index (if ,is-list ,seq 0)))
(while (if ,is-list
(consp ,index)
(< ,index (seq-length ,seq)))
(let ((,(car spec) (if ,is-list
(car ,index)
(seq-elt ,seq ,index))))
,@body
(setq ,index (if ,is-list
(cdr ,index)
(+ ,index 1)))))
,@(if (cddr spec)
`((setq ,(car spec) nil) ,@(cddr spec))))))
(while (if ,length
(< ,index ,length)
(consp ,index))
(let ((,(car spec) (if ,length
(prog1 (seq-elt ,seq ,index)
(setq ,index (+ ,index 1)))
(pop ,index))))
,@body))
;; FIXME: Do we really want to support this?
,@(cddr spec))))
(defun seq-drop (seq n)
"Return a subsequence of SEQ without its first N elements.
@ -350,7 +347,10 @@ This is an optimization for lists in `seq-take-while'."
(defalias 'seq-each #'seq-do)
(defalias 'seq-map #'mapcar)
(add-to-list 'emacs-lisp-mode-hook #'seq--activate-font-lock-keywords)
(unless (fboundp 'elisp--font-lock-flush-elisp-buffers)
;; In Emacs≥25, (via elisp--font-lock-flush-elisp-buffers and a few others)
;; we automatically highlight macros.
(add-to-list 'emacs-lisp-mode-hook #'seq--activate-font-lock-keywords))
(provide 'seq)
;;; seq.el ends here