Skip to content

Commit

Permalink
Fix off-by-one regression in --iterate
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
basil-conto committed Feb 28, 2021
1 parent 0e97578 commit 3deba09
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 8 deletions.
15 changes: 9 additions & 6 deletions dash.el
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
9 changes: 7 additions & 2 deletions dev/examples.el
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 3deba09

Please sign in to comment.