Am Fr., 9. Sept. 2022 um 21:35 Uhr schrieb Amirouche <xxxxxx@hyper.dev>:


------- Original Message -------
On Friday, September 9th, 2022 at 21:01, Marc Nieper-Wißkirchen <xxxxxx@gmail.com> wrote:

Am Fr., 9. Sept. 2022 um 20:55 Uhr schrieb Amirouche <xxxxxx@hyper.dev>:
# Abstract

Procedures that take procedures as argument, and return procedures, namely: combinators.
The procedures identify essential complexity. Their use allows keeping the code terse,
readable, and reduce the need for convenience procedures.

"Readable" is very subjective. Personally, I prefer less terse code that writes out some of the procedures in this SRFI as explicit lambda terms.

I use the word readable here to describe the value proposition: “what you will get”, the “How” in the rationale, i.e., “less fragmentation”. Yes, it is subjective, it is also different depending on people prior experience. Here, the important words are 'identify essential complexity'. That library put a name on widespread code practices [citation needed].

# Rationale

Many procedures take a procedure as argument (map, filter, fold, filter...), that leads to two situations:

- The code use a lambda to describe the needed behavior, that is a composition of existing procedures, and often enough it spans on multiple lines…

- It is argued that it is better to move the lambda into a define, which requires finding a good name, and split the action into different locations, making the code harder to read.

Who argues this regularly outside the C or Python (or [insert any insufficiently functional programming language]) community?

I read that in a Clojure guide, I can't find it at https://guide.clojure.style/. Anyway, to keep the code readable I recommend laying out the body of a procedure following the algorithm: top-down, left-to-right, and often a lambda passed as an argument grow big and on multiple lines that it breaks the 5-ideas at most in my head, hence break the scan flow, example:

  (filter (lambda (g) (or (odd? g) (complex? g) (infinite? g)) (iota 42))

Where the following is easier to scan, hence read:

  (filter (disjoin odd? complex? infinite?) (iota 42))

I usually format the above as

(filter (lambda (g)
          (or (odd? g) (complex? g) (infinite? g)))
        (iota 42))

but this is definitely a question of personal style.

As a side remark: Using `iota` like this shouldn't be used with great care as it constructs a list in memory which is then discarded.  The loop facility I am currently working on (as most other loop facilities) provides idioms that allow one to write equally clear code without extra pressure on the garbage collector.

 



Those composition procedures, called combinators that were identified by the Scheme, and Common Lisp communities, allow making existing libraries more versatile, and future code more readable, keeping the code dense, by reducing fragmentation, and still readable.

See my "readability" remark above.

Do you agree that SRFI-235, re-use known or essential idioms in procedure composition, and can reduce fragmentation in the code that use them?

Yes, it is good that SRFI 235 provides standard names for many idioms.  So code that actually uses these idioms becomes more readable because it helps people to recognize common patterns.  My objection was just about any claim of better absolute readability.  What I mean is that while using higher-order procedures and similar abstractions may lead to terser and more "fancy" code, it is quite subjective whether it is more readable, so that in itself would not be a good rationale.
 
(People have made the same points in favor and against SRFI 26, for example.)st

SRFI 26 use a very terse syntax, small number of char, and introduce at least one new idiom with the symbol <>. It may be readable after some training, it certainly leads to a stepper learning curve.