jackfirth / rebellion

A collection of core libraries for Racket
https://pkgs.racket-lang.org/package/rebellion
Apache License 2.0
80 stars 15 forks source link

Continuation-based transducers #364

Open jackfirth opened 4 years ago

jackfirth commented 4 years ago

There should be a way to write transducer implementations such that the state of the transducer is modeled implicitly using control flow. This would make it easier to implement transducers by writing them in a generator-like style. Example:

(define (mapping f)
  (transducer
    (let loop ()
      (define next (consume!))
      (emit! (f next))
      (loop))))

The consume! and emit! forms should be syntax parameters that transducer binds to delimited continuations. There should also be some way of handling the half-close step, either by returning an option from consume! or by adding a separate try-consume! form.

The performance of doing this is expected to be absolutely awful, because each time an element is consumed or emitted a continuation has to be captured. This shouldn't be used to implement transducers in the standard library. However, it's great for hacking something together quickly and for teaching people how transducers work.

For the implementation, it may be helpful to consult this gist I put together that shows how to implement different kinds of control flow structures using continuations and syntax parameters.

jackfirth commented 4 years ago

Idea: a #:repeat? argument that, when true, is equivalent to wrapping the transducer body in a loop that runs forever. This is similar to #337 and to infinite-generator)).