1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-15 02:20:21 -08:00

* 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 example
@end defun @end defun
@defmac seq-doseq (var sequence [result]) body@dots{} @defmac seq-doseq (var sequence) body@dots{}
@cindex sequence iteration @cindex sequence iteration
This macro is like @code{dolist}, except that @var{sequence} can be a list, This macro is like @code{dolist}, except that @var{sequence} can be a list,
vector or string (@pxref{Iteration} for more information about the vector or string (@pxref{Iteration} for more information about the

View file

@ -44,31 +44,28 @@
(defmacro seq-doseq (spec &rest body) (defmacro seq-doseq (spec &rest body)
"Loop over a sequence. "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. 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))) (declare (indent 1) (debug ((symbolp form &optional form) body)))
(let ((is-list (make-symbol "is-list")) (let ((is-list (make-symbol "is-list"))
(seq (make-symbol "seq")) (seq (make-symbol "seq"))
(index (make-symbol "index"))) (index (make-symbol "index")))
`(let* ((,seq ,(cadr spec)) `(let* ((,seq ,(cadr spec))
(,is-list (listp ,seq)) (,length (if (listp ,seq) nil (seq-length ,seq)))
(,index (if ,is-list ,seq 0))) (,index (if ,is-list ,seq 0)))
(while (if ,is-list (while (if ,length
(consp ,index) (< ,index ,length)
(< ,index (seq-length ,seq))) (consp ,index))
(let ((,(car spec) (if ,is-list (let ((,(car spec) (if ,length
(car ,index) (prog1 (seq-elt ,seq ,index)
(seq-elt ,seq ,index)))) (setq ,index (+ ,index 1)))
,@body (pop ,index))))
(setq ,index (if ,is-list ,@body))
(cdr ,index) ;; FIXME: Do we really want to support this?
(+ ,index 1))))) ,@(cddr spec))))
,@(if (cddr spec)
`((setq ,(car spec) nil) ,@(cddr spec))))))
(defun seq-drop (seq n) (defun seq-drop (seq n)
"Return a subsequence of SEQ without its first N elements. "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-each #'seq-do)
(defalias 'seq-map #'mapcar) (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) (provide 'seq)
;;; seq.el ends here ;;; seq.el ends here