Skip to content

Commit 2bbc589

Browse files
committed
feat: transduce for bit-vector
1 parent c549bf3 commit 2bbc589

3 files changed

Lines changed: 35 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- Reducer: `partition` for splitting the stream results.
1212
- Reducer: `base-string` for reducing into a `simple-base-string`.
1313
- Reducer: `bit-vector` for reducing into a `bit-vector`.
14+
- Can now `transduce` over a `bit-vector` (e.g. `#*0101`).
1415

1516
#### Changed
1617

tests/tests.lisp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,8 @@
238238
(t:transduce #'t:pass #'t:cons (t:plist '(:a 1 :b 2 :c 3))))
239239
(fail (t:transduce #'t:pass #'t:cons 1))
240240
(is equal (list 3 2 1) (t:transduce #'t:pass #'t:cons (t:reversed #(1 2 3))))
241-
(is equal nil (t:transduce #'t:pass #'t:cons (t:reversed #()))))
241+
(is equal nil (t:transduce #'t:pass #'t:cons (t:reversed #())))
242+
(is equal #*0101 (t:transduce #'t:pass #'t:bit-vector #*0101)))
242243

243244
(define-test "Higher Order Transducers"
244245
:depends-on (reduction transduction)

transducers/entry.lisp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ sources. See `sources.lisp' and `entry.lisp' for examples of how to do this.
5252
"))
5353

5454
(defmethod transduce (xform f (source cl:string))
55+
"Elements are indexed via `char'."
5556
(string-transduce xform f source))
5657

5758
(defmethod transduce (xform f (source list))
@@ -60,16 +61,23 @@ streamed as-is as cons cells."
6061
(list-transduce xform f source))
6162

6263
(defmethod transduce (xform f (source cl:vector))
64+
"Elements are indexed via `aref'."
6365
(vector-transduce xform f source))
6466

6567
(defmethod transduce (xform f (source reversed))
68+
"Operate over a vector in reversed order."
6669
(reversed-transduce xform f source))
6770

71+
(defmethod transduce (xform f (source cl:bit-vector))
72+
"Elements are indexed via `bit'."
73+
(bit-vector-transduce xform f source))
74+
6875
(defmethod transduce (xform f (source cl:hash-table))
6976
"Yields key-value pairs as cons cells."
7077
(hash-table-transduce xform f source))
7178

7279
(defmethod transduce (xform f (source pathname))
80+
"Opens the file and yields individual lines."
7381
(file-transduce xform f source))
7482

7583
(defmethod transduce (xform f (source generator))
@@ -157,6 +165,30 @@ streamed as-is as cons cells."
157165
#+nil
158166
(vector-transduce (map #'1+) #'cons #(1 2 3 4 5))
159167

168+
(declaim (ftype (function (t t cl:bit-vector) *) bit-vector-transduce))
169+
(defun bit-vector-transduce (xform f coll)
170+
(let* ((init (funcall f))
171+
(xf (funcall xform f))
172+
(result (bit-vector-reduce xf init coll)))
173+
(funcall xf result)))
174+
175+
(declaim (ftype (function (t t cl:bit-vector) *) bit-vector-reduce))
176+
(defun bit-vector-reduce (f identity vec)
177+
(declare (optimize (speed 3) (safety 1) (debug 1)))
178+
(let ((len (length vec)))
179+
(labels ((recurse (acc i)
180+
(declare (type fixnum i))
181+
(if (= i len)
182+
acc
183+
(let ((acc (funcall f acc (bit vec i))))
184+
(if (reduced? acc)
185+
(reduced-val acc)
186+
(recurse acc (1+ i)))))))
187+
(recurse identity 0))))
188+
189+
#+nil
190+
(bit-vector-transduce (map #'1+) #'cons #*0101)
191+
160192
(defun reversed-transduce (xform f coll)
161193
(let* ((init (funcall f))
162194
(xf (funcall xform f))

0 commit comments

Comments
 (0)