Commit e224c946 authored by Stefan Monnier's avatar Stefan Monnier

* 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.
parent 18a78f82
......@@ -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
......@@ -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))))
(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))))
;; 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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment