aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gtwiwtg.lisp17
1 files changed, 14 insertions, 3 deletions
diff --git a/gtwiwtg.lisp b/gtwiwtg.lisp
index 35f830d..bb377e1 100644
--- a/gtwiwtg.lisp
+++ b/gtwiwtg.lisp
@@ -409,13 +409,19 @@ Error Condition:
(stop gen)))))
-(defun inflate! (fn gen)
+(defun inflate! (fn gen &key extra-cleaup)
"FN is expected to be a function that accepts elements of GEN and
returns a new generator.
The generator (INFLATE! FN GEN) generates each element of an
intermediate generator (FN X) for each X generated by GEN.
+When a thunk is supplied to EXTRA-CLEANUP, then that thunk will be
+called when the inflated generator is stopped. EXTRA-CLEANUP exists
+for the case when FN returns generators that are not being created
+within the body of FN, but are merely being \"looked up\" somehow. See
+the implementation of CONCAT! for an example.
+
Here is an example:
> (let ((keys (seq '(:name :occupation :hobbies)))
@@ -457,7 +463,8 @@ Error Conditions:
:clean-up
(lambda ()
(stop gen)
- (when sub-gen (stop sub-gen)))))))
+ (when sub-gen (stop sub-gen))
+ (when extra-cleanup (funcall extra-cleanup)))))))
(defun concat! (gen &rest gens)
@@ -469,7 +476,11 @@ Error Conditions:
- If any of the generators has been used elsewhere, an error will be sigalled.
"
(sully-when-clean (list* gen gens))
- (inflate! #'identity (seq (list* gen gens))))
+ (inflate! #'identity (seq (list* gen gens))
+ ;; in the case that not all arguments are consumed,
+ ;; explicitly stop each one at clean-up time.
+ :extra-cleanup (lambda ()
+ (dolist (g (list* gen gens)) (stop g)))))
(defun zip! (gen &rest gens)
"Is a shortcut for (MAP! #'LIST GEN1 GEN2 ...)"