AtlatestRenderedmarkdown
Readme

sigil-transducers

Composable transducer library for Sigil. Provides polymorphic sequence operations and transducer pipelines that work across lists, vectors, arrays, and dicts.

Installation

Add to your package.sgl dependencies:

(from-git url: "codeberg:sigil/sigil-transducers")

Usage

Polymorphic Operations

When imported, (sigil seq) provides polymorphic versions of common operations that work on any collection type:

(import (sigil seq))

(map square '(1 2 3))       ; => (1 4 9)
(map square #(1 2 3))       ; => #(1 4 9)
(filter even? '(1 2 3 4))   ; => (2 4)
(filter even? #(1 2 3 4))   ; => #(2 4)
(fold + 0 '(1 2 3 4))       ; => 10
(any even? '(1 3 4 5))      ; => #t
(every even? '(2 4 6))      ; => #t
(find even? '(1 3 4 5))     ; => 4

Transducers

Transducers are composable transformation pipelines that separate what to transform from how to iterate:

(import (sigil seq))

(define xform
  (comp (filtering even?)
        (mapping square)
        (taking 5)))

(transduce xform conj '() (iota 100))  ; => (0 4 16 36 64)

Transducer Constructors

  • (mapping f) - Transform each element by applying f
  • (filtering pred) - Keep only elements satisfying pred
  • (taking n) - Take at most n elements, then stop
  • (dropping n) - Skip the first n elements
  • (taking-while pred) - Take elements while pred is true
  • (dropping-while pred) - Drop elements while pred is true
  • cat - Flatten one level of nesting
  • (mapcat f) - Map then concatenate

Composition

Compose transducers left-to-right with comp:

(comp (filtering even?) (mapping square) (taking 3))

Execution

  • (transduce xform rf init coll) - Apply transducer xform with reducing function rf, initial value init, over collection coll
  • (into to xform from) - Transform and collect into a collection of the same type as to
  • (sequence xform coll) - Transform a collection, preserving its type

Reducers

  • conj - Build lists (via cons)
  • conj-vec - Build vectors (builds list, convert with into)
  • conj-dict - Build dicts from (key . value) pairs

Stream Processing

Transducers also work for processing channel message streams:

(import (sigil seq)
        (sigil channels)
        (sigil async))

(define log-xform
  (comp (filtering (lambda (msg) (equal? (dict-ref msg level:) "error")))
        (mapping (lambda (msg) (dict-ref msg text:)))))

(with-async
  (go (for-each (lambda (msg) (channel-send logs msg)) messages)
      (channel-close! logs))
  (go (for-channel (msg logs)
        (let ((xrf (log-xform (lambda (acc x) (println "ERROR: ~a" x) acc))))
          (xrf #f msg)))))

License

BSD-3-Clause