[plt-dev] is there some reason that port->lines et al. don't close input port?

From: Carl Eastlund (cce at ccs.neu.edu)
Date: Mon May 24 16:28:42 EDT 2010

On Mon, May 24, 2010 at 4:22 PM, John Clements
<clements at brinckerhoff.org> wrote:
> On May 24, 2010, at 1:11 PM, Matthew Flatt wrote:
>> At Mon, 24 May 2010 11:12:56 -0700, John Clements wrote:
>>> Is there a good reason why port->lines doesn't close the input port?
>> An eof-of-file doesn't necessarily mean an end-of-stream, and error
>> handling usually requires extra effort to close a port, which is why we
>> usually use functions like `with-input-form-file'. Probably, though,
>> it's mostly that port-reading functions don't normally close the port.
>>> Perhaps there
>>> could be an optional argument that allowed this behavior?
>> An optional keyword argument seems ok to me.
> How about:
> (port->lines p #:close-on-eof? #t)
> implemented something like this:
> extra optional arguments in port.rkt:
> ...
> (define (port->lines [p (current-input-port)] #:line-mode [mode 'any] #:close-on-eof? [close-on-eof? #f])
>  (port->x-lines 'port->lines p mode read-line close-on-eof?))
> (define (port->bytes-lines [p (current-input-port)] #:line-mode [mode 'any] #:close-on-eof? [close-on-eof? #f])
>  (port->x-lines 'port->bytes-lines p mode read-bytes-line close-on-eof?))
> ...
> additional explicit arg in portlines.rkt:
> (define (port->x-lines who p mode read-line close-on-eof?)
>  (unless (input-port? p)
>    (raise-type-error who "input-port" p))
>  (check-mode who mode)
>  (let loop ([l null])
>    (let ([line (read-line p mode)])
>      (if (eof-object? line)
>          (begin0 (reverse l)
>                  (when close-on-eof?
>                    (close-input-port p)))
>          (loop (cons line l))))))
> If this makes sense, I'll add docs (and a test case, if there are existing rackety test cases for things like this).
> N.B.: Nothing here is committed yet, and I'm not proposing this for 5.0.
> John


If you want something consistent with existing functions, it sounds
like a "with-input-from-url" would do what you want.  We don't often
have readers close a port, but we do have functions that open, use,
and close a port all in one operation.


Posted on the dev mailing list.