chore: reorganize transducer definition

This commit is contained in:
Edward
2021-01-04 00:48:49 -08:00
parent 6aebcfe4dc
commit 5bca9a117f
4 changed files with 83 additions and 36 deletions

View File

@ -23,7 +23,9 @@
:serial t
:in-order-to ((test-op (test-op :data-lens/transducer/test)))
:components ((:file "package")
(:file "transducers")))
(:file "transducer-protocol")
(:file "transducers")
(:file "lazy-sequence")))
(asdf:defsystem #:data-lens/transducer/test
:description "tests for the transducers"

58
lazy-sequence.lisp Normal file
View File

@ -0,0 +1,58 @@
(in-package :data-lens.transducers)
(defclass lazy-sequence ()
((%next :initarg :next :reader next)))
(defun lazy-sequence (next)
(make-instance 'lazy-sequence :next next))
(defmethod reduce-generic ((seq lazy-sequence) (func function) init)
(let ((next (next seq)))
(loop for next-val = (funcall next)
for acc = init then next-acc
for next-acc = (when next-val (funcall func acc next-val))
while next-val
finally (return acc))))
(defmacro repeating (v)
`(lazy-sequence
(lambda ()
,v)))
(defun repeating* (v &key count)
(lazy-sequence
(if count
(let ((iterations 0))
(lambda ()
(when (< iterations count)
(prog1 v
(incf iterations)))))
(lambda ()
v))))
(defun iota (&key (start 0) (step 1) count)
(lazy-sequence
(funcall
(compile nil
`(lambda ()
(declare (optimize (speed 3) (debug 1) (safety 1)))
(let ((init ,start)
,@(serapeum:unsplice (when count
'(iterations 0))))
(declare (type (integer ,start
,(if count
(+ start (* count step))
'*))
init)
,@(serapeum:unsplice
(when count
`(type (integer 0 ,count) iterations))))
(lambda ()
(declare (optimize (speed 3)))
(,@(if count
`(when (< iterations ,count))
'(progn))
(prog1 init
(incf init ,step)
,@(serapeum:unsplice
(when count
'(incf iterations))))))))))))

22
transducer-protocol.lisp Normal file
View File

@ -0,0 +1,22 @@
(in-package :data-lens.transducers.internals)
(defgeneric unwrap (it obj)
(:method (it obj) obj))
(defgeneric init (it))
(defgeneric stepper (it))
(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)))

View File

@ -1,26 +1,3 @@
(in-package :data-lens.transducers.internals)
(defgeneric unwrap (it obj)
(:method (it obj) obj))
(defgeneric init (it))
(defgeneric stepper (it))
(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)))
(in-package :data-lens.transducers)
(declaim (inline mapping filtering deduping catting splitting
@ -213,18 +190,6 @@
(defmethod unwrap ((it (eql 'list-builder)) obj)
(cdr (elt obj 0)))
(defclass lazy-sequence ()
((%next :initarg :next :reader next)))
(defun lazy-sequence (next)
(make-instance 'lazy-sequence :next next))
(defmethod reduce-generic ((seq lazy-sequence) (func function) init)
(let ((next (next seq)))
(loop for next-val = (funcall next)
for acc = init then next-acc
for next-acc = (when next-val (funcall func acc next-val))
while next-val
finally (return acc))))
(defmacro comment (&body body)
(declare (ignore body))
nil)