From baa40f9568fc52825453abec59f120cf7ca06bcc Mon Sep 17 00:00:00 2001 From: Earl Hyatt Date: Fri, 13 Aug 2021 21:05:03 -0400 Subject: [PATCH] Add macro `seq-setq`. * lisp/emacs-lisp/seq.el (seq-setq): New macro. This macro is the 'setq' version of 'seq-let'. * doc/lispref/sequences.texi (seq-setq): Document this macro. * test/lisp/emacs-lisp/seq-tests.el (test-seq-setq): Test this macro. --- doc/lispref/sequences.texi | 17 +++++++++++++++++ lisp/emacs-lisp/seq.el | 8 ++++++++ test/lisp/emacs-lisp/seq-tests.el | 24 ++++++++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index 545fd408f8..20816ce8ca 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -1111,6 +1111,23 @@ Sequence Functions destructuring binding, see @ref{Destructuring with pcase Patterns}. @end defmac +@defmac seq-setq var-sequence val-sequence +@cindex sequence destructuring + This macro works similarly to @code{seq-let}, except that values are +assigned to variables as if by @code{setq} instead of as in a +@code{let} binding. + +@example +@group +(let ((a nil) + (b nil)) + (seq-setq (_ a _ b) '(1 2 3 4)) + (list a b)) +@result{} (2 4) +@end group +@end example +@end defmac + @defun seq-random-elt sequence This function returns an element of @var{sequence} taken at random. diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index e8fc4a2814..f0dc283f57 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -93,6 +93,14 @@ seq-let (declare (indent 2) (debug (sexp form body))) `(pcase-let ((,(seq--make-pcase-patterns args) ,sequence)) ,@body)) + +(defmacro seq-setq (args sequence) + "Assign to the variables in ARGS the elements of SEQUENCE. + +ARGS can also include the `&rest' marker followed by a variable +name to be bound to the rest of SEQUENCE." + (declare (debug (sexp form))) + `(pcase-setq ,(seq--make-pcase-patterns args) ,sequence)) ;;; Basic seq functions that have to be implemented by new sequence types diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el index 05c7fbe781..44e855e2cf 100644 --- a/test/lisp/emacs-lisp/seq-tests.el +++ b/test/lisp/emacs-lisp/seq-tests.el @@ -383,6 +383,30 @@ test-seq-let (should (null b)) (should (null c))))) +(ert-deftest test-seq-setq () + (with-test-sequences (seq '(1 2 3 4)) + (let (a b c d e) + (seq-setq (a b c d e) seq) + (should (= a 1)) + (should (= b 2)) + (should (= c 3)) + (should (= d 4)) + (should (null e))) + (let (a b others) + (seq-setq (a b &rest others) seq) + (should (= a 1)) + (should (= b 2)) + (should (same-contents-p others (seq-drop seq 2))))) + (let ((a) + (seq '(1 (2 (3 (4)))))) + (seq-setq (_ (_ (_ (a)))) seq) + (should (= a 4))) + (let (seq a b c) + (seq-setq (a b c) seq) + (should (null a)) + (should (null b)) + (should (null c)))) + (ert-deftest test-seq-min-max () (with-test-sequences (seq '(4 5 3 2 0 4)) (should (= (seq-min seq) 0)) -- 2.25.1