# HG changeset patch # User Steve Losh # Date 1479850835 0 # Node ID 1c23d569319274f0a19943e962fbc8f492749d9f # Parent 66fc93caa1c653f00d942bb8d9fae09b70f22214 Add `every-nth` iterate driver diff -r 66fc93caa1c6 -r 1c23d5693192 losh.lisp --- a/losh.lisp Tue Nov 22 20:07:42 2016 +0000 +++ b/losh.lisp Tue Nov 22 21:40:35 2016 +0000 @@ -1210,6 +1210,56 @@ (next ,control))))) +(defmacro-driver (FOR var EVERY-NTH n DO form) + "Iterate `var` numerically modulo `n` and run `form` every `n`th iteration. + + The driver can be used to perform an action every N times through the loop. + + `var` itself will be a counter that counts up from to to `n - 1`. + + `generate` is supported. + + Example: + + (iterate (for i :from 1 :to 7) + (print `(iteration ,i)) + (for tick :every-nth 3 :do (print 'beep)) + (print `(tick ,tick)) (terpri)) + ; => + (ITERATION 1) + (TICK 0) + + (ITERATION 2) + (TICK 1) + + (ITERATION 3) + BEEP + (TICK 2) + + (ITERATION 4) + (TICK 0) + + (ITERATION 5) + (TICK 1) + + (ITERATION 6) + BEEP + (TICK 2) + + (ITERATION 7) + (TICK 0) + + " + (let ((kwd (if generate 'generate 'for))) + (with-gensyms (counter limit) + `(progn + (with ,limit = ,n) + (generate ,counter :modulo ,limit :from 0) + (,kwd ,var :next (prog1 (next ,counter) + (when (= ,counter (1- ,limit)) + ,form))))))) + + (defun keywordize-clause (clause) (iterate (for (k v . nil) :on clause :by #'cddr) diff -r 66fc93caa1c6 -r 1c23d5693192 package.lisp --- a/package.lisp Tue Nov 22 20:07:42 2016 +0000 +++ b/package.lisp Tue Nov 22 21:40:35 2016 +0000 @@ -125,6 +125,7 @@ :across-flat-array :averaging :cycling + :every-nth :for-nested :in-array :in-lists