Fix off-by-one regression in --iterate

* dash.el (--iterate): Evaluate FORM N-1, not N, times, fixing a
regression in Dash 2.18.0.  Don't evaluate INIT if N is zero, fixing
a bug since the introduction of the macro.

* dev/examples.el (-flatten-n): Add regression test.
(-iterate): Test for superfluous evaluations.

Fixes #373.
master
Basil L. Contovounesios 5 years ago
parent 0e97578208
commit 3deba098ab
No known key found for this signature in database
GPG Key ID: 205AB54A5D5D8CFF
  1. 15
      dash.el
  2. 9
      dev/examples.el

@ -685,12 +685,15 @@ Thus function FN should return a list."
(defmacro --iterate (form init n)
"Anaphoric version of `-iterate'."
(declare (debug (form form form)))
(let ((res (make-symbol "result")))
`(let ((it ,init) ,res)
(dotimes (_ ,n)
(push it ,res)
(setq it ,form))
(nreverse ,res))))
(let ((res (make-symbol "result"))
(len (make-symbol "n")))
`(let ((,len ,n))
(when (> ,len 0)
(let* ((it ,init)
(,res (list it)))
(dotimes (_ (1- ,len))
(push (setq it ,form) ,res))
(nreverse ,res))))))
(defun -iterate (fun init n)
"Return a list of iterated applications of FUN to INIT.

@ -343,7 +343,8 @@ new list."
(-flatten-n 3 '((1 2) ((3 4) ((5 6))))) => '(1 2 3 4 5 6)
(-flatten-n 0 '(3 4)) => '(3 4)
(-flatten-n 0 '((1 2) (3 4))) => '((1 2) (3 4))
(-flatten-n 0 '(((1 2) (3 4)))) => '(((1 2) (3 4))))
(-flatten-n 0 '(((1 2) (3 4)))) => '(((1 2) (3 4)))
(-flatten-n 1 '(((1 . 2)) ((3 . 4)))) => '((1 . 2) (3 . 4)))
(defexamples -replace
(-replace 1 "1" '(1 2 3 4 3 2 1)) => '("1" 2 3 4 3 2 "1")
@ -606,7 +607,11 @@ value rather than consuming a list to produce a single value."
(--iterate nil nil 0) => ()
(--iterate nil nil 1) => '(nil)
(--iterate nil nil 2) => '(nil nil)
(--iterate (setq it -1) 1 3) => '(1 -1 -1))
(--iterate (setq it -1) 1 3) => '(1 -1 -1)
(let (l) (--iterate (push 1 l) (push 0 l) -1) l) => ()
(let (l) (--iterate (push 1 l) (push 0 l) 0) l) => ()
(let (l) (--iterate (push 1 l) (push 0 l) 1) l) => '(0)
(let (l) (--iterate (push 1 l) (push 0 l) 2) l) => '(1 0))
(defexamples -unfold
(-unfold (lambda (x) (unless (= x 0) (cons x (1- x)))) 10) => '(10 9 8 7 6 5 4 3 2 1)

Loading…
Cancel
Save