Browse code
chore: reorganize transducer definition
Edward authored on 04/01/2021 08:48:49
Showing 4 changed files
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) |