This is the mail archive of the guile@sourceware.cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: running programs.


>>>>> "Friedrich" == Friedrich Dominicus <Friedrich.Dominicus@inka.de> writes:

    Friedrich> you can do a (run (| (ls) (grep linux )))

That's exactly as I remember it.  

    Friedrich> As mentioned above (run (| (ls) (grep)))
    Friedrich> just works fine.

I didn't mean to imply it didn't work.  I find the syntax a bit
strained.

    Friedrich> IMO Oliver has tried to hide shell-programming as far
    Friedrich> away and instead offer a Scheme as Shell-Programming
    Friedrich> language. If you read his paper I would be astonished
    Friedrich> to find that he want's a Schemeish access to the Shell.

I assume your talking about his 94 scsh paper.  It's been quite a
while since I've looked at it, but I've dug it out of my files again.

    Friedrich> And BTW isn't (run (| ( .... prefix I can't see that
    Friedrich> there isn't it looks in my eyes very simular to let's
    Friedrich> say '+' etc.

That would be fine, except you don't add programs together in a pipe;
each program operates on the result of the proceeding program.  Since
programs are operators I'd like them to look like operators and scheme
is a prefix language.  

One of my main difficulties with scsh is it avoids using scheme
intrinsics in favor of terseness.  Take the run pipe syntax (run
(prog1) (< file)).  Scheme has file ports and this could just have
well been (run (prog1 arg1) (open-input-port "file"))... bingo less
new syntax.  In most systems, a new program is run by specifying a
program name, and program arguments as strings, so why not follow that
lead.  It has the benefit of not adding new syntax to the language, so
now I have (run ("prog1" "arg1") (open-input-port "file")).  For the
simple case of one program, a list of optional arguments can be used
instead of a list of strings, so why not (run "prog1" "arg1"
(open-input-file "file"))?  Of course, in scsh run returns the process
status, but if it returned an input port connected to the output of
the program then the pipe syntax becomes obvious (run "prog2" (run
"prog1" (open-input-file))).  The obvious problem is that the return
status is not available, but guile supports keywords so there is no
reason not to use them, (run #:wait "prog1") or

(run #:started (lambda (pid) 
	         (let ((status (cadr (waitpid pid))))
		   ..do something..))
       "prog1" input-port)

where #:started specifies a procedure that gets called after the
new process has been forked/execed.  This has the advantage that I can
write code like this: 

(let ((pids '()))
     (run #:stdout #f
	  #:started (lambda (pid) (set! pids (cons pid pids)))
	  "prog1"
	  (run #:started (lambda (pid) (set! pids (cons pid pids)))
	       "prog2"))
     ..use the pids as necessary..)       
	      
Although this example is a bit strained, it demonstrates my point.
With a rather limited set of keyword arguments all of the features
supported by scsh can be handled.

Scsh is not designed for guile, so it doesn't use all the features
that guile supports.  To a large extent, scsh is a complete extended
language based on scheme in much the same way as guile.  Using scsh
inside guile means reimplementing the scsh language on top of the
guile interpreter and necessarily introducing alternate ways of doing
things.  Why not build on top of guile's strong points?  Guile is
already very good at scripting *except* open-pipe is rather limited
and many scsh extensions are unneeded.

Bear in mind, my not liking scsh's syntax does not mean I think it's
intrinsically bad.  However, I do think that guile might be better
suited by a different interface to run external programs.

Cheers,

Clark

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]