From: anders@lise11.lise.unit.no (Anders Christensen)
Subject: Re: Capturing System Command Output (was: SH Backquote)
Organization: /home/flipper/anders/.organization
	<19920819090033SEB1525@MVS.draper.com>
Date: 19 Aug 92 23:16:49

In article <19920819090033SEB1525@MVS.draper.com> SEB1525@MVS.draper.com (Steve Bacher) writes:

> In article <ANDERS.92Aug18223235@lise8.lise.unit.no>,
> anders@lise8.lise.unit.no (Anders Christensen) writes:

> >The three different _conceptual_ methods that I am aware of are
> [following very abbreviated]
> >
> >      files = 'ls'(directory)
> >      'ls' directory ' >LIFO'     /* or "|rxstack" */
> >       'ls | rxstack'
> >      rcode = popen( "ls" directory,, "ls-output" )
> 
> Er, our *four* different conceptual methods...?

No, three. _For_the_user_ it is three different conceptual methods,
since both ">LIFO" and "|rxstack" is the same Rexx programming
concepts. The concepts of implementation, well that is a completely
different thing.

I'd like this debate to differ between the concepts of Rexx
programming, and concepts of implementation. It is important to design
a good syntax, and _then_ do the implementation, instead of deciding
on an implementation and the design a suitable syntax for it. 

In the latter case, you are going to get an syntax ridden with
implementation specific details and lots of special cases. And it will
probably only be really useful to the persons that know the opsys
specific details that the implementation builds on. If the point of
view is: "Wouldn't it be nice if feature XXX of opsys YYY would be
available in Rexx?" You are guaranteed to get: 1) unportable Rexx
implementations; 2) unportable Rexx scripts; 3) 'unportable' Rexx
users (knowing Rexx is not enough to move to another platform, you
have to know the features of the operating system too).

Therefore, can we discuss a _syntax_ first, and try to keep concepts
of how to _implement_ that syntax away until we have evaluated how
good the various syntaxes are, and we need to know how implementable
they are?

> Just from the UI POV, how about a fifth:
>
>	  rcode = queue_to_stack("ls" directory)

OK, this very well illustrates the the main conceptual question, which
is : COMMANDS vs FUNCTIONS.

The '>LIFO' and '|rxstack' methods are COMMAND-driven, all the other 
are FUNCTION-driven. I'd like to see a good command-driven interface.
And why? Because the concept of "anything not a keywords falls through
to the outer environment" is just so elegant. A rexx program is
basically just a list of commands to an environment. And then you can
add Rexx keywords to create a structure in those commands. That is the
the magic of Rexx: The structure of a programming language to be added
on top of an unintelligent command interpreter. 

On the other hand, in a function-driven based approach, the commands
are put _into_ the Rexx language, as parameters to Rexx functions. I
think that is far less elegant, and (more important) I think that the
resulting code and structure is far less obvious.

> Similar syntactically to popen(), but captures stdout and puts it
> on the data stack or in stem variables a la EXECIO.

There are three different approaches: 1) put it on the stack; 2) put
it into variables; and 3) let it be an expression. All of them have
weeknesses and strengths, so perhaps all three should be possible to
do. But what _syntax_ to use for each single method?

> And what about stderr?  Maybe an optional third argument could
> specify the destination for stderr.  (Let's not get fancy and
> start specifying destinations for file descriptor numbers...)

Well, 'stderr' is a Unix-concept. If the starting point is "how to
handle stderr", we'll end up with a system tailored for Unix. I'd
rather pose the question like: what about other I/O streams than
standard input and standard output. Other opsys'es (e.g. like VMS)
have more I/O streams, even more than Unix' three.

> I don't like the ">LIFO" syntax because that conflicts with a
> valid file-redirection spec, using up potential file names in
> a magic-cookie sort of way. 

I don't like it either, but for another reason. It might fool users
who know about redirection into believing that this is some sort of
redirection.  If someone has a better notation for it, please tell me!

>                              Also, this and the piping and popen
> solutions are too Unix-oriented in coding style; the programming
> interface to get at the data should be in the REXX culture, not
> the culture of the surrounding OS.  This would also get around
> the "address something-other-than-the-native-shell" problem
> you alluded to with the 'address ftp; "ls | rxqueue"' difficulty.

Yes!!! Exactly!

However, there _are_ no REXX culture on how to 'move' information from
the outer environment into the rexx interpreter. TRL avoids the
problem, assuming that the environment itself knows how to put things
on the stack, or otherwise communicate with the interpreter. There is
an IBM culture that use the stack heavily, and there are non-IBM
cultures that use linein/lineout/etc heavily. But there is no One Way. 

> [speculation on how to implement deleted]

Shall we start by trying to find a good syntax? Intuitive, clear,
userfriendly (yuk, that's a buzz-word!), conceptual clean, etc, etc?

> >A better solution might be to label the _methods_ rather than the
> >_interpreters_, then it would be possible to check whether an
> >interpreter supports e.g. the popen-based method. Then the user don't
> >have to update his rexxscripts to support new interpreters, but new
> >interpreters will support the already existing methods.

> No, a better solution would be to have one method.  Dispatching on
> whether a particular syntax is used is just as bad as, and possibly
> worse than, dispatching on a particular implememntation.

I don't feel convinced that we will find One method. At best, we might
arm a function with enough parameters and options to cover all
situations. But I don't think a battleship-sized function would be the
best solution.

-anders
Comments: Gated by NETNEWS@AUVM.AMERICAN.EDU