git.fiddlerwoaroof.com
Browse code

chore: reorganize transducer definition

Edward authored on 04/01/2021 08:48:49
Showing 4 changed files
... ...
@@ -23,7 +23,9 @@
23 23
   :serial t
24 24
   :in-order-to ((test-op (test-op :data-lens/transducer/test)))
25 25
   :components ((:file "package")
26
-               (:file "transducers")))
26
+               (:file "transducer-protocol")
27
+               (:file "transducers")
28
+               (:file "lazy-sequence")))
27 29
 
28 30
 (asdf:defsystem #:data-lens/transducer/test
29 31
   :description "tests for the transducers"
30 32
new file mode 100644
... ...
@@ -0,0 +1,58 @@
1
+(in-package :data-lens.transducers)
2
+
3
+(defclass lazy-sequence ()
4
+  ((%next :initarg :next :reader next)))
5
+(defun lazy-sequence (next)
6
+  (make-instance 'lazy-sequence :next next))
7
+
8
+(defmethod reduce-generic ((seq lazy-sequence) (func function) init)
9
+  (let ((next (next seq)))
10
+    (loop for next-val = (funcall next)
11
+          for acc = init then next-acc
12
+          for next-acc = (when next-val (funcall func acc next-val))
13
+          while next-val
14
+          finally (return acc))))
15
+
16
+(defmacro repeating (v)
17
+  `(lazy-sequence
18
+    (lambda ()
19
+      ,v)))
20
+
21
+(defun repeating* (v &key count)
22
+  (lazy-sequence
23
+   (if count
24
+       (let ((iterations 0))
25
+         (lambda ()
26
+           (when (< iterations count)
27
+             (prog1 v
28
+               (incf iterations)))))
29
+       (lambda ()
30
+         v))))
31
+
32
+(defun iota (&key (start 0) (step 1) count)
33
+  (lazy-sequence
34
+   (funcall
35
+    (compile nil
36
+             `(lambda ()
37
+                (declare (optimize (speed 3) (debug 1) (safety 1)))
38
+                (let ((init ,start)
39
+                      ,@(serapeum:unsplice (when count
40
+                                             '(iterations 0))))
41
+                  (declare (type (integer ,start
42
+                                          ,(if count
43
+                                               (+ start (* count step))
44
+                                               '*))
45
+                                 init)
46
+                           ,@(serapeum:unsplice
47
+                              (when count
48
+                                `(type (integer 0 ,count) iterations))))
49
+                  (lambda ()
50
+                    (declare (optimize (speed 3)))
51
+                    (,@(if count
52
+                           `(when (< iterations ,count))
53
+                           '(progn))
54
+                     (prog1 init
55
+                       (incf init ,step)
56
+                       ,@(serapeum:unsplice
57
+                          (when count
58
+                            '(incf iterations))))))))))))
0 59
new file mode 100644
... ...
@@ -0,0 +1,22 @@
1
+(in-package :data-lens.transducers.internals)
2
+
3
+(defgeneric unwrap (it obj)
4
+  (:method (it obj) obj))
5
+(defgeneric init (it))
6
+(defgeneric stepper (it))
7
+
8
+(defgeneric reduce-generic (seq func init)
9
+  (:method ((seq sequence) (func function) init)
10
+    (reduce func seq :initial-value init))
11
+  (:method ((seq sequence) (func symbol) init)
12
+    (reduce func seq :initial-value init))
13
+  (:method (seq (func symbol) init)
14
+    (reduce-generic seq
15
+                    (symbol-function func)
16
+                    init))
17
+  (:method ((seq hash-table) (func function) init)
18
+    (let ((acc init))
19
+      (maphash (lambda (k v)
20
+                 (setf acc (funcall func acc (list k v))))
21
+               seq)
22
+      acc)))
... ...
@@ -1,26 +1,3 @@
1
-(in-package :data-lens.transducers.internals)
2
-
3
-(defgeneric unwrap (it obj)
4
-  (:method (it obj) obj))
5
-(defgeneric init (it))
6
-(defgeneric stepper (it))
7
-
8
-(defgeneric reduce-generic (seq func init)
9
-  (:method ((seq sequence) (func function) init)
10
-    (reduce func seq :initial-value init))
11
-  (:method ((seq sequence) (func symbol) init)
12
-    (reduce func seq :initial-value init))
13
-  (:method (seq (func symbol) init)
14
-    (reduce-generic seq
15
-                    (symbol-function func)
16
-                    init))
17
-  (:method ((seq hash-table) (func function) init)
18
-    (let ((acc init))
19
-      (maphash (lambda (k v)
20
-                 (setf acc (funcall func acc (list k v))))
21
-               seq)
22
-      acc)))
23
-
24 1
 (in-package :data-lens.transducers)
25 2
 
26 3
 (declaim (inline mapping filtering deduping catting splitting
... ...
@@ -213,18 +190,6 @@
213 190
 (defmethod unwrap ((it (eql 'list-builder)) obj)
214 191
   (cdr (elt obj 0)))
215 192
 
216
-(defclass lazy-sequence ()
217
-  ((%next :initarg :next :reader next)))
218
-(defun lazy-sequence (next)
219
-  (make-instance 'lazy-sequence :next next))
220
-(defmethod reduce-generic ((seq lazy-sequence) (func function) init)
221
-  (let ((next (next seq)))
222
-    (loop for next-val = (funcall next)
223
-          for acc = init then next-acc
224
-          for next-acc = (when next-val (funcall func acc next-val))
225
-          while next-val
226
-          finally (return acc))))
227
-
228 193
 (defmacro comment (&body body)
229 194
   (declare (ignore body))
230 195
   nil)