Adam Faiz writes: > From fe113e9efc08aae2a7e3792a1018c496212bd774 Mon Sep 17 00:00:00 2001 > From: AwesomeAdam54321 > Date: Sun, 15 Dec 2024 23:48:30 +0800 > Subject: [PATCH v3] rdelim: Add new procedure `for-line-in-file`. > > * module/ice-9/rdelim.scm (for-line-in-file): Add it. > > This procedure makes it convenient to do per-line processing of a text > file. > --- > module/ice-9/rdelim.scm | 23 ++++++++++++++++++++++- It should also be documented in the manual I would think. > 1 file changed, 22 insertions(+), 1 deletion(-) > > diff --git a/module/ice-9/rdelim.scm b/module/ice-9/rdelim.scm > index d2cd081d7..b4c55c12e 100644 > --- a/module/ice-9/rdelim.scm > +++ b/module/ice-9/rdelim.scm > @@ -23,7 +23,8 @@ > ;;; similar to (scsh rdelim) but somewhat incompatible. > > (define-module (ice-9 rdelim) > - #:export (read-line > + #:export (for-line-in-file > + read-line > read-line! > read-delimited > read-delimited! > @@ -206,3 +207,23 @@ characters to read. By default, there is no limit." > line) > (else > (error "unexpected handle-delim value: " handle-delim))))) > + > +(define* (for-line-in-file file proc What about naming it for-delimited-in-file and adding #:delims argument? That would allow reading files that have "lines" terminated with #\nul instead of just #\newline, which would be handy for processing output of shell commands (-z, -0, ...). Delims could default to "\n", so ergonomics of your use case would not be impacted. On completely separate note, having (fold|reduce)-delimited-in-file would be cool too (/me makes a note to write it). > + #:key (encoding #f) (guess-encoding #f)) > + "Call PROC for every line in FILE until the eof-object is reached. > +FILE can either be a filename string or an already opened input port. > +The corresponding port is closed upon completion. > + > +The line provided to PROC is guaranteed to be a string." > + (let ((port > + (if (input-port? file) > + file > + (open-input-file file > + #:encoding encoding > + #:guess-encoding guess-encoding)))) > + (let loop ((line (read-line port))) > + (cond ((eof-object? line) > + (close-port port)) I know you were told that it should close the port, but I am not sure about it. It should close the port it opened, but should it also the one it got? This will prevent the same port being processed multiple times, which could be annoying. > + (else > + (proc line) > + (loop (read-line port))))))) Have a nice day, Tomas -- There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.