A transducer is a kind of sequence transformation that comes with guarantees about memory usage and about how much of the sequence is consumed in between each produced output. Transducers are first class objects that chain together fluently, without any macros involved. For example, this code defines a function that finds and reports all of the lines in a string that are longer than 80 characters and it uses no macros at all:
(require rebellion/streaming/reducer
rebellion/streaming/transducer)
(define (report-all-long-lines str)
(transduce str
(batching into-line)
enumerating
(filtering long-line?)
#:into (into-for-each report-long-line)))
(define (long-line? e)
(define line (enumerated-element e))
(> (string-length line) 80))
(define (report-long-line e)
(define line (enumerated-element e))
(define number (enumerated-position e))
(printf "Line ~a is longer than 80 characters: ~a\n" number line))
You may find transducers more useful than for-style loops in the following cases:
For some real-world examples of transducers in action, I cannot thank Sam Phillips enough for putting together
this gist containing scripts he wrote for his day job using transducers.