git.fiddlerwoaroof.com
Raw Blame History
(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)))

#+(or)
(defun document (&rest strings)
  (serapeum:string-join strings #.(format nil "~2%")))

(defgeneric init (client))
(defgeneric stepper (client))
(defgeneric unwrap (client obj)
  (:method (client obj) obj))
(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"))

(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)))))))

(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)

(defdocumentation transducer-protocol
  (: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.")
  (:generic-function unwrap (client obj)
                     )
  (:generic-function unwrap (client obj)
                     )
  (:generic-function unwrap (client obj)
                     ))