git.fiddlerwoaroof.com
transducer-protocol.lisp
5bca9a11
 (in-package :data-lens.transducers.internals)
 
 (defgeneric reduce-generic (seq func init)
   (:method ((seq sequence) (func function) init)
     (reduce func seq :initial-value init))
   (:method ((seq sequence) (func symbol) init)
     (reduce func seq :initial-value init))
   (:method (seq (func symbol) init)
     (reduce-generic seq
                     (symbol-function func)
                     init))
   (:method ((seq hash-table) (func function) init)
     (let ((acc init))
       (maphash (lambda (k v)
                  (setf acc (funcall func acc (list k v))))
                seq)
       acc)))
96cc36bb
 
bd9ef2fb
 #+(or)
 (defun document (&rest strings)
   (serapeum:string-join strings #.(format nil "~2%")))
 
96cc36bb
 (defgeneric init (client))
 (defgeneric stepper (client))
 (defgeneric unwrap (client obj)
   (:method (client obj) obj))
bd9ef2fb
 (defgeneric builder-for-input (seq)
   (:documentation
    "Take a transducible sequence, return a builder and an init value for that builder.
 
 CONSTRAINT: SEQ should be copied, not modified"))
96cc36bb
 
 (defun exit-early (acc)
   (throw 'done acc))
 
 (defun transduce (xf build seq)
   (let* ((xf (etypecase xf
                (list (apply 'alexandria:compose xf))
                ((or function symbol) xf)))
          (transducer (funcall xf (stepper build))))
     (unwrap build
             (funcall transducer
                      (catch 'done
                        (reduce-generic seq
                                        transducer
                                        (init build)))))))
 
bd9ef2fb
 (defun into (to xf from)
   (multiple-value-bind (builder init) (builder-for-input to)
     (let* ((xf (etypecase xf
                  (list (apply 'alexandria:compose xf))
                  ((or function symbol) xf)))
            (transducer (funcall xf (stepper builder))))
       (unwrap builder
               (funcall transducer
                        (catch 'done
                          (reduce-generic from
                                          transducer
                                          init)))))))
 
 (defmacro defdocumentation (name &body doc-specs)
   name doc-specs
   nil)
 
96cc36bb
 (defdocumentation transducer-protocol
bd9ef2fb
   (:function transduce (xf builder seq)
              "Run a transducer XF over sequence SEQ using BUILDER to accumulate results.
 
 Uses the generic function REDUCE-GENERIC so transducers work over lazy
 sequences and hash tables.")
96cc36bb
   (:generic-function unwrap (client obj)
                      )
   (:generic-function unwrap (client obj)
                      )
   (:generic-function unwrap (client obj)
                      ))