General question Marc Nieper-Wißkirchen (02 May 2020 18:59 UTC)
Re: General question Linus Björnstam (03 May 2020 17:12 UTC)
Re: General question Marc Nieper-Wißkirchen (03 May 2020 17:48 UTC)
Re: General question John Cowan (03 May 2020 17:56 UTC)
Re: General question Marc Nieper-Wißkirchen (03 May 2020 18:09 UTC)
Re: General question Lassi Kortela (03 May 2020 18:09 UTC)
Re: General question Lassi Kortela (03 May 2020 18:12 UTC)
Re: General question Linus Björnstam (03 May 2020 20:02 UTC)
Re: General question Marc Nieper-Wißkirchen (04 May 2020 06:34 UTC)

Re: General question Linus Björnstam 03 May 2020 17:12 UTC

Hi Marc!

You are right that the use cases overlap, and currently all it boils down to is eager vs lazy semantics (or push vs pull). There is a slight difference in ergonomics in that you can extend a transducer on both sides:

    (define t (compose (tmap (lambda (x) (* x x))) (tfilter even?)))
    (list-transduce (compose t (tmap add1)) rcons (iota 100))
    (vector-transduce (compose (tmap add1) t) rcons (list->vector (iota 100)))

This can of course be emulated in srfi-158 with some use of cut (or maybe a future extension to generators, where something like (gmap add1) would be like (cut gmap add1 <>)).

In clojure I think the prime example is the use of transducers as an extra argument when creating channels. When pushing a message through a channel, you can "pre-process" it/filter it/whatever before pushing it into the channel. The same can of course be achieved with a generator, but I personally find the ergonomics of it slightly off. Personally I see them as a protocol for transformations of data flowing in one direction. With generators that is done "downstream" of the data, with transducers it is done "upstream".

In the future I would like to write an extra reference implementation without hidden mutable state. Pure transparent transducers. In languages like c++ that can be done with very little overhead, whereas scheme makes that tricky. The Atria library for C++ has this kind of transducers. Very cool! The talk is here: https://www.youtube.com/watch?v=vohGJjGxtJQ

I also don't know how fast the generator reference implementation is, but the overhead has been higher in the two schemes I tried (guile and chez). Simple things like (faster-than-reference-generator-fold + 0 (gfilter odd? (gmap add1 (list->generator a-list))) takes about 2x longer than (list-transduce (compose (tmap add1) (tfilter odd?)) + a-list) in guile3. Both of these schemes start boxing things as fast as they see a set!, thought, so that might be the case.

Best regards
  Linus Björnstam

On Sat, 2 May 2020, at 20:59, Marc Nieper-Wißkirchen wrote:
> Hi!
>
> This is the first time I have taken a closer look at the transducers
> provided by this SRFI. In view of the earlier SRFI 158, the use cases
> of this SRFI are not yet clear to me.
>
> Could someone explain to me what SRFI 171 adds what cannot be done
> with the generators and accumulators of SRFI 158 and a trivial
> procedure that takes a generator and an accumulator and feeds the
> values of the generator into the accumulator until the generator is
> exhausted and then returns the accumulated value?
>
> Marc
>