Cyclic ports from other ports, truncating the input? Jeronimo Pellegrini (09 Jul 2026 20:33 UTC)
Re: Cyclic ports from other ports, truncating the input? Wolfgang Corcoran-Mathe (10 Jul 2026 02:50 UTC)
Re: Cyclic ports from other ports, truncating the input? Jeronimo Pellegrini (10 Jul 2026 12:16 UTC)
Re: Cyclic ports from other ports, truncating the input? Wolfgang Corcoran-Mathe (10 Jul 2026 16:23 UTC)
Re: Cyclic ports from other ports, truncating the input? Jeronimo Pellegrini (11 Jul 2026 00:02 UTC)

Re: Cyclic ports from other ports, truncating the input? Wolfgang Corcoran-Mathe 10 Jul 2026 02:50 UTC

Jeronimo,

Thanks for you comment.

On 2026-07-09 17:33 -0300, Jeronimo Pellegrini wrote:
> The SRFI proposes procedures to read cyclically from strings and
> bytevectors. Wouldn't it also make sense to have a convenience
> procedure to make a cyclic port from another non-cyclic one,
> specifying a number of (characters or bytes) to be read from the
> other port? Or does it feel like unnecessary convenience?

I believe this could work, although it has some odd implications.  You
might use such a procedure to produce the contents of a file repeatedly
without slurping the entire contents at once.  (I can't think of a use
case, at the moment.)

A cyclic port made from another input port P would probably read a byte
or character at a time until N items have been read (or until P returns
EOF), then continue producing those items _ad infinitum_.  It would
eventually need θ(N) space in which to store those items, but that
could be allocated gradually.  (Alternatively, if P is positionable,
the cyclic port could simply reset P's position and keep reading
whenever a cycle is complete.)

Are we on the same track so far?

The thing that bothers me about this idea is that reading from or
setting the position of P after calling 'input-port->cyclic-port' (or
whatever) on it may change the state of the cyclic port.  This is
already an issue (which I forgot to address in the first draft) with
string- or bytevector-backed cyclic ports, but it seems a lot worse
when the cyclic port's input is another port.  You can always pass
'open-cyclic-input-bytevector' a copy of a bytevector, but there's no
portable way to copy a port.

For example,

    (define p1 (open-input-bytevector #u8(1 2 3 4))

    (define p2 (input-port->cyclic-port p1))

    (read-u8 p2)  ; => 1
    (read-u8 p1)  ; => 2 (probably)
    (read-u8 p2)  ; => 3 (probably)

And that's one of the simpler interactions.

If we want this feature, in short, we have to accept ports that read
from other ports that read from ... and the convoluted chains of side
effects they could entail.  I'm not yet convinced it's worth it.

--
Wolfgang Corcoran-Mathe  <xxxxxx@sigwinch.xyz>