From: Hoehle, Joerg-C. <Joe...@t-...> - 2003-06-05 16:17:02
|
Hi, here are my (unasked for) comments on this issue: >> I'm slighltly confused about making it user-level. It is very similar >> to run-program and run-shell-command but it is more `direct' and does >We already have a whole bunch of built-in functions that do >similar things: SHELL, MAKE-PIPE-INPUT-STREAM, MAKE-PIPE-OUTPUT-STREAM, >MAKE-PIPE-IO-STREAM. >That's more than enough. >I want to have just one single built in. >Let us make LAUNCH user-level only when it has absorbed all the >functionality of the 4 other commands, and implement them as calling >LAUNCH and deprecate them. I'm opposed to such global removal. It's would be a Schemesque approach (i.e. "why do you need catch/throw/block/return/ignore-errors/handler-case when all is needed is call/cc?"). Another argument to this issue is: higher-level stuff (e.g. ignore-errors) is usually easier to mimic than passing through a single primitive (i.e. call/cc). For instance, a naive (mini) CL on top of a JVM would easily provide IGNORE-ERRORS. It cannot easily provide handler-bind, because exception semantics are really different (cf. unwinding of stack in exceptional situations). Please leave in a kiss-style (SHELL &optional cmd+args), which does several things: + ability to suspend CLISP, portably invoking a user-shell shell (please don't tell me that I can just open another X window). + ability to trust the programmer or user when s/he knows exactly what to pass to the shell instead of having CLISP second-guess quoting issues on all systems or situations where the execvlpe() family of calls may not be used. Second-guessing is always going to fail in some situations, typically where a cygwin-compiled program tries to invoke a native one, or vice-versa. o Similarly, make-pipe-... stream are easy to comprehend and relatively easy to implement, even without a full-featured launch. E.g. On AmigaOS, it could be nothing more than (open "APIPE:ls mydev:foo sort" :direction :input), on systems where the freeware APIPE device handler is installed. LAUNCH may possibly allow more features, e.g. have the programmer choose whether stderr goes or not to a single Lisp-input-stream shared with stdout. That's a definitive plus. >(with-open-file (null "/dev/null" :direction :output :if-exists :append) o Please support :stream nil or some such convention, because having the programmer to use "/dev/null" in code will immediately loose the portability that CLISP tries to maintain. Heck, I use CLISP for its portability! People, please try to avoid gratuitous system dependencies. o a PID is an abstract data type where portability matters. On UNIX it's known to be a small integer (for better or worse[*]), on MS-Windows it may very well be a pointer (don't know), and on AmigaOS it *is* a pointer. It will be hard for (LAUNCH :asynchronous t) to return a portable thing -- at least return an abstract/opaque thing. >But I have never created lisp types from scratch. In some situations (e.g. rexx-send-command) we used to just return a FOREIGN-POINTER object. Formerly, we used a simple bit-vector -- at least it was something else than an integer, and EQ-ness could be checked for, preventing fake arguments! What I mean here is it can be enough to agree to either document that the exact type is purposely not documented and to be considered opaque, even though it may happen to be an integer on some systems, or document all OS cases. (dotimes (i 10000) (posix:kill i)) is perfectly fine, since for POSIX, pids are tiny integers (or am I wrong here?). Enough said, maybe I shall go Python instead. [*] Please write an essay on the pros and cons of open() etc. using small integers vs. fopen() using FILE pointers. I'd be happy to discuss such design issues with everybody. What I did not say (yet): o I consider execxyz() a good thing, because it avoids tcl-style madness (the quoting problem, also known to linguists) to some extent. BTW, did you ever use find -o or -exec on UNIX? o I also consider having EXT:[:]LAUNCH a good thing (but not that MS-Windows specific :indirect keyword, which is not understandable per se). o Launch's ability to generate the equivalent of pipe-input/output-streams for use in Lisp is also valuable. o I'd maybe provide a portable :priority setting (:high/:low/:normal mapping to OS&context dependent values) for portability-aware programmers. It's just cheap to do so. o Having two distinct Lisp-side streams for reading stdout & stderr command output can result in deadlocks. o An advantage of MAKE-PIPE-*-STREAM over LAUNCH is that it does not have to deal with producing PID objects/values that the programmer doesn't care about. That's another reason why it's easier to implement or provide portably (cf. call/cc). o BTW, I think I've seen MAKE-PIPE-*-STREAM produce zombies (or just unusable processes) on Linux (e.g. forgetting about the stream and having the GC get (or not?) rid of it). Regards, Jorg Hohle. |