ba5b4efb5872

Add iterate (for ... seed ... then ...) driver
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Sat, 23 Feb 2019 22:46:27 -0500
parents e844dad54ef3
children 3cf5a5efd686
branches/tags (none)
files package.lisp src/iterate.lisp

Changes

--- a/package.lisp	Sat Feb 23 22:30:19 2019 -0500
+++ b/package.lisp	Sat Feb 23 22:46:27 2019 -0500
@@ -351,6 +351,8 @@
     :test
     :timing
     :within-radius
+    :seed
+    :then
 
     ))
 
--- a/src/iterate.lisp	Sat Feb 23 22:30:19 2019 -0500
+++ b/src/iterate.lisp	Sat Feb 23 22:46:27 2019 -0500
@@ -665,3 +665,29 @@
        (,kwd ,var = ,expr))))
 
 
+(defmacro-driver (FOR var SEED seed THEN then)
+  "Bind `var` to `seed` initially, then to `then` on every iteration.
+
+  This differs from `(FOR … FIRST … THEN …)` and `(FOR … INITIALLY … THEN …)`
+  because `then` is evaluated on every iteration, *including* the first.
+
+  Example:
+
+    (iterate
+      (repeat 3)
+      (for x :first     0 :then (1+ x))
+      (for y :initially 0 :then (1+ y))
+      (for z :seed      0 :then (1+ z))
+      (collect (list x y z)))
+    ; =>
+    ((0 0 1)
+     (1 1 2)
+     (2 2 3))
+
+  "
+  (let ((kwd (if generate 'generate 'for)))
+    `(progn
+       (,kwd ,var :next ,then)
+       (initially (setf ,var ,seed)))))
+
+