[racket] fun with ports and (system ..) calls

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Wed Oct 16 14:30:49 EDT 2013

At Wed, 16 Oct 2013 13:48:57 -0400, Vlad Kozin wrote:
> Yep, closing the port did the trick. Thanks David and Matthew. 
> I wonder though if this is practical in a general case. Say, I expect
> more data and want to grab it as it appears. Something like calling
> "tail -10" on a file that's being updated. I thought flushing the
> port would do, but it doesn't.

When you use `(for/list ((line (in-lines in))) ...)` the `in-lines`
sequence doesn't end until an EOF is available --- but a line can be
received anyway, as long as newline is found to terminate the line.

For example,

 (define-values (in out) (make-pipe))
 (parameterize ((current-output-port out))
    (system (format "find . ~a ~a" "-name \"*.c\"" "-print")))
 (for ((line (in-lines in)))
   (displayln line))

doesn't end, since `out` is never closed, but lines are parsed and
displayed along the way.

Similarly, in

> Here's an example of IO from the Guide:
> ---------------------------------------
> Examples:
> > (define-values (in out) (make-pipe))
> > (write "hello" out)
> > (read in)
> "hello"
> > (write '("alphabet" soup) out)
> > (read in)
> '("alphabet" soup)
> Why does this work?

the closing quotes allow "hello" to be read, and the closing
parenthesis allows '("alphabet" soup) to be read, even though no
end-of-file is available for the input end of the pipe.

Posted on the users mailing list.