Subject: Re: bug#26338: 26.0.50; Collect all matches for REGEXP in current buffer

From: Philipp Stephani <[email-masked]>
Date: Sat, 22 Apr 2017 19:42:15 +0000

Tino Calancha <[email-masked]> schrieb am Sa., 8. Apr. 2017 um
17:20 Uhr:

>
> >
> >       Your point is about performance.
> >
> >
> > No, I care mostly about clarity, simplicity, and good API design,
> including separation of concerns.
> Expressibity and readability might be some kind of clarity.
>

Yes, but it seems we mean different things with these words. "Readability"
for me means (among other things) that each logical entity has a single
purpose. The single purpose of the (already way too complex) cl-loop macro
is iterating over things. It doesn't concern itself with the things it
should iterate over and where they come from.

> I totally agree about API design and separation of concerns.
> >
> >         I am driven by easy to write code.
> >       Maybe you can provide an example about how to write those things
> using
> >       the iter-by cl-loop clause.
> >
> >
> > Sure:
> >  (require 'generator)
> > (iter-defun re-matches (regexp)
> >   (while (re-search-forward regexp nil t)
> >     (iter-yield (match-string 0))))
> > (iter-do (m (re-matches (rx digit)))
> >   (print m))
> > (cl-loop for m iter-by (re-matches (rx digit))
> > do (print m))
> Thank you very much for your examples.  They are nice.  I am not
> as familiar as you with generators.  I must study them more.
>
> Between A) and B), the second looks at least as simple and clear as
> the first one, and probably more readable.
>

I disagree. (A) clearly separates the generation of the stream of objects
to iterate over from the iteration, (B) doesn't. (A) is extensible to any
kind of iteration as long as it can be expressed using generators (or
lists, vectors, ...), while for (B) you need a new keyword for every new
thing to iterate over.

>
> A)
> (iter-defun re-matches (regexp)
>    (while (re-search-forward regexp nil t)
>      (iter-yield (match-string-no-properties 1))))
>
> (cl-loop for m iter-by (re-matches "^(defun \\(\\S +\\)")
>           collect m)
>
> B)
> (cl-loop for m the matches of "^(defun \\(\\S +\\)"
>           collect m)