About gchain-generators Amirouche Boubekki (21 Feb 2021 10:11 UTC)
Re: About gchain-generators John Cowan (25 Feb 2021 02:01 UTC)

About gchain-generators Amirouche Boubekki 21 Feb 2021 10:11 UTC

I am not certain about the naming, they are existing procedures
similarly named with a `g` prefix, followed by a verb then possibly
something. That is confusing in the regard of other R7RS forms that
follow the template: typename-verb. My proposal is to call it
generator-chain or take inspiration from threading macros, if it makes
sense to someone else.

The current signature is:

  (gchain-generators constr . ops)

Then the description introduces the term "operation". It seems to me
it would be easier for the mind to just call them procedures `proc` to
avoid too many terms in the scheme vocabulary (maybe we need more
vocabulary?)

Also the signature presentation mislead into thinking that that form
is useful on its own:

- the following (gchain-generators constr) is nop.

- the following (gchain-generators constr op) is equivalent to (proc (constr))

That is, gchain-generators is useful starting with two ops:
(gchain-generators constr op1  op2)

I want to stress the similarity with a threading macro and unlike the
compose form I know about, it can be read from left to right and that
is the order of execution. Without gchain-generators the above code
is:

  (op2 (op1 (constr)))

In srfi-168, I have similar form that is a macro:

    (define-syntax nstore-query
      (syntax-rules ()
        ((_ value) value)
        ((_ value f rest ...)
         (nstore-query (f value) rest ...))))))

I think the macro is more readable such as:

    (define-syntax generator-chain
      (syntax-rules ()
        ((_ value) value)
        ((_ generator proc rest ...)
         (generator-chain (proc generator) rest ...))))))

The naming of the first rule is done on purpose: the last proc of the
chain can produce something that is not a generator, for instance if
it computes a sum. But that is an edge case, anyway, in user code it
is prolly easier to read as two lines:

  (define selection (gchain-generators (lambda () (make-iota-generator
100)) (lambda (g) (gfilter odd? g)))
  (define sum (generator-fold + 0 selection))

A difference with the macro, the first argument is a generator, not a
thunk constructor, it is not clear to me what are the consequences,
except that the macro becomes simpler to implement because the first
argument is a generator, and proc / operations produce generators too,
unlike gchain-generator where the first argument is a lambda
constructor, then all ops produce generators.

Do we want a macro for gchain-generators ?