Thanks a lot for clearing this up. I was looking at the sources in the GitHub
repo linked from the egg Wiki page:
https://github.com/scheme-requests-for-implementation/srfi-127/blob/master/lseqs/lseqs-impl.scm
The implementation there is as follows (and my simplified one was derived from
that):
(define lseq-for-each
(case-lambda
((proc) (error "lseq-for-each: missing arguments"))
((proc lseq) ; 1-sequence fast path
(let loop ((lseq lseq))
(if (null? lseq)
(if #f #f)
(begin
(proc (lseq-car lseq))
(loop (lseq-cdr lseq))))))
((proc . lseqs) ; variadic path
(let loop ((lseqs lseqs))
(if (any-null? lseqs)
(if #f #f)
(begin
(apply proc (map lseq-car lseqs))
(loop (map lseq-cdr lseqs))))))))
It did not occur to me that the egg sources are completely different:
https://code.call-cc.org/egg-tarballs/5/srfi-127/srfi-127-1.3.tar.gz
Would it make sense to update the egg? lseq-for-each as a wrapper around
lseq-realize makes little sense and may end up in a confusion when used.
The documentation does (implicitly) hint that lseq-for-each is lazy:
The arguments to lseq-for-each are like the arguments to lseq-map, but
lseq-for-each calls proc for its side effects rather than for its values.
Unlike lseq-map, lseq-for-each is guaranteed to call proc on the elements of
the lseqs in order from the first element(s) to the last, and the value
returned by lseq-for-each is unspecified. If none of the lseqs are finite,
lseq-for-each never returns.
—
Stan
> On 22 Feb 2026, at 20:20, Kon Lovett <[email protected]> wrote:
>
> ;; Eagerly apply a proc to the elements of lseqs
> ;; Included because it's a common operation, even though it is trivial
> (define (lseq-for-each proc . lseqs)
> (apply for-each proc (map lseq-realize lseqs)))
>
> lseq-for-each* applies the proc before processing the remaining list, not the
> egg source.
>
>
>> On Feb 22, 2026, at 10:22 AM, Stanislav Kljuhhin via Chicken-users
>> <[email protected]> wrote:
>>
>> Hello,
>>
>> Consider the following minimal example:
>>
>> ---8<---
>> (import srfi-18)
>> (import srfi-121)
>> (import srfi-127)
>>
>> (define (emit yield)
>> (let loop ((i 1))
>> (thread-sleep! 1)
>> (yield "hello")
>> (when (< i 10)
>> (loop (add1 i)))))
>>
>> (define (collect s)
>> (display s)
>> (newline))
>>
>> (define (lseq-for-each* proc lseq)
>> (unless (null? lseq)
>> (proc (lseq-car lseq))
>> (lseq-for-each* proc (lseq-cdr lseq))))
>>
>> (lseq-for-each collect (generator->lseq (make-coroutine-generator emit)))
>> ---8<—--
>>
>> When I run this program (compiled or interpreted, makes no difference),
>> nothing
>> happens for 10 seconds, then 10 hello's are printed at once. But if I use the
>> in-place implementation lseq-for-each*, then the program behaves as one might
>> expect, i.e. hello's are printed with a 1-second interval.
>>
>> Here I used a simplified implementation of lseq-for-each*, just for brevity,
>> but
>> we can copy the SRFI-127 implementation verbatim, and it still works the
>> same.
>>
>> Can you help me understand what is going on, please?
>>
>> —
>> Stan
>