diff options
-rw-r--r-- | gtwiwtg.lisp | 17 |
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 ...)" |