Sure.  The objection to extending the port abstraction is practical.  Most systems other than R6RS ones don't have extensibility of ports.  String ports have been around a long time, and even then the SRFI and R7RS have one set of rules and R6RS another (in which fetching the current content of a string output port has the side-effect of clearing it).  Libraries based on generators are far more likely to be portable, precisely because generators are simple procedures that all Schemes already have.

Chicken 4 had a continuation API, but it was abandoned in Chicken 5 because nobody used it.  Walking the stack is inherently unportable, because trampolining or Cheney-on-the-MTA implementations don't have a stack as such; Chicken error tracebacks report the last N calls without regard to any notion of stack depth.

On Wed, Sep 4, 2019 at 8:31 AM Marc Feeley <> wrote:

> On Sep 4, 2019, at 8:20 AM, John Cowan <> wrote:
> I missed sending this to SRFI 170.
> ---------- Forwarded message ---------
> From: John Cowan <>
> Date: Tue, Sep 3, 2019 at 5:56 PM
> Subject: Re: Outstanding issue: directory-files in the context of huge directories
> To: <>
> So here's the generator:
> (define make-directory-files-generator
>   (case-lambda
>     ((dir dot-files?) (make-directory-files-generator* dir dot-files?))
>     ((dir) (make-directory-files-generator* dir #f))))
> (define (make-directory-files-generator* dir dot-files?)
>   (let ((dir-obj (open-directory dir dot-files?))
>           (eof (eof-object)))
>     (lambda ()
>       (let ((f (read-directory dir-obj)))
>         (if (eq? f eof) (close-directory dir-obj))
>         f))))
> I haven't actually tested this, but it's at least conceptually correct.
> Although this overlaps the utility of directory-files, I want to preserve the latter (and Harold agrees).  When WG1 voted on the issue, directory-files was the highest-ranking result in the STV voting; however, it did not command a majority of the votes cast, which is why it does not appear in R7RS-small.

Unfortunately, with this “generators” abstraction, there is no way to put a timeout on generating the next value.

In Gambit all ports, including directory ports but also pipes and network listen sockets, have a timeout setting so that it is possible to indicate that the caller isn’t willing to block for more than a given amount of time, something that is essential for real time systems.  In other words, ports are a more powerful abstraction than generators (thunks).  It reminds me of the problem with the use of procedures to represent continuations created by call/cc, which then can’t be used for more advanced continuation operations (such as walking the stack, knowing who the caller is, accessing the continuation’s environment, etc).