Subject: [clisp-list] Re[4]: Separate Unix error stream keyword for ext:run-shell-comma nd

From: "Hoehle, Joerg-Cyril" <[email-masked]>
Date: Wed Jun 11 05:07:07 2003

Arseny Slobodjuck wrote:
>Try to see it this way: streams and running external programs are
>highly "non-FP" things.
That is no argument to a fan of Haskell :-)

> Launch is the function to run programs, not
>creating streams, brewing beer and sending the mail. Streams are
>'additional' to it, not essential.

I see it like this: pipes are connectors. It is then a matter of taste and subject for debate whether connectors exist by themselves or not.
The fact that pipes may be represented as objects has IMHO nothing to do in this debate (a red herring).

One can also take another approach: pipes/streams are essential, not foreign programs. The reason is that the only thing I can see is the I/O via pipes. So that's what matters to me.
The only observable "reality" is my interaction with the foreign world: it looks like foreign programs exist, but I cannot be sure of that; however pipes for sure exist, I have a grasp on them.
I.e. streams are essential, programs are not :-)
MAKE-PIPE-*-STREAM IMHO adheres to this point of view: The pipe stream and what flows through it is what matters to Lisp, not the program being invoked.

> There are already closed streams. When
>the program under pipe stream is finished, what do we have ? Exactly
>the same - a pipe stream with invalid process handle.

The implementation of FIFO that I maintained for some time was controllable so as not to die together with a program. It had independent life/extent. It could be put to life before a program would be started, and/or remain there after one died.

BTW, even UNIX pipe live a little longer than some of the programs connected to them. I.e. they buffer the last few KB of output. But I forgot about SIGPIPE issues. This was discussed once upon a time in this list.

>What if the user tries to read from stream after it's finished ?
That's a protocol error in my view. In certain situations, it can be statically derived from program source. It's like the pop(empty_stack) problem to me.

Regards,
	Jorg Hohle.

---

From: "Hoehle, Joerg-Cyril" <[email-masked]>
Date: Wed Jun 11 05:07:08 2003

Hi,

Actually, a zero-arity (MAKE-PIPE-INPUT-STREAM) makes sense with named pipes or fifos. As a stream, it could even have a pathname that could be communicated to external programs (in lieu of the "-" pseudo-file name that some programs recognize for either stdin or stout.

But I don't expect that to be as portable as the unary MAKE-PIPE-INPUT-STREAM, presumably because it's a less-used pattern.

For example, on AmigaOS, there is a utility to pipe with any program that does not do i/o via stdin/out like /bin/cat. E.g. let's pretend GNU diff would not recognize the pseudo filename "-". I could then write
	pipe cat myfile | diff IN: otherfile
since cat myfile | diff - outfile would not work.

This works with every program. And it eliminates some needs for stdin/out redirection.
E.g.		gcc -E ... >/tmp/foo
becomes	gcc -E -o OUT: ...
(LAUNCH "gcc"
  :arguments (list* "-E" "-o" (pathname (setq s (make-pipe-input-stream))) other-options))
(read-char s)

I recently learnt that bash/zsh (not old sh/csh) have a similar feature: <(command) and >(command)
The <() construct creates a FIFO (either a "named pipe" or /dev/fd/n), and passes the name as an argument.
	diff <(cat myfile) otherfile

But if you go that way, you need to devise a protocol for when you have finished with the resource. Would CLOSE be enough?

Regards,
	Jorg Hohle.