[comp.sys.amiga] AREXX the low/medium level standard - NEXT THE HIGH LEVEL

gary@eddie.MIT.EDU (Gary Samad) (03/30/88)

Eight THOUSAND unread messages in comp.sys.amiga!?!  I know I haven't
been on for a little while, but...jeez...


Well, hi again!  I've come back to look in on the IPC conversations that
I've been hearing about.  I've spent some time following all of the
related threads that I could find;  and, I have an important point to make
as a bonafide commercial developer with a real commercial product
(Microfiche Filer).  

     LATER IN THIS MESSAGE I'M GOING TO ASK YOU FOR
YOUR COMMENTS CONCERNING A HIGH LEVEL STANDARD.  YOUR SUGGESTIONS MIGHT
ACTUALLY MAKE IT INTO A COMMERCIAL PRODUCT!

First of all, there were some very interesting ideas expressed about
an object oriented system, an IFF based system, a device based system,
a broadcast message system, function servers, name servers, and so on.
The discussions have ranged from the highest levels to the lowest
(and I must smile about the fact that some people were seriously examining
the subject of FindPort being too slow, while the messages contained
IFF format structures, the parsing of which would dwarf the time needed
to do a FindPort! :-).

I would like to point out that there already exists a low and medium
level standard that is sufficiently powerful to mediate conversations
between applications and provide control mechanisms - AREXX!  ARexx may not
be THE perfect solution (I personally have some problems with the
language syntax), but it does meet the 'sufficiently powerful' test
by being fully programmable and allowing the passing of ANY data in
ANY format between concurrently running applications.

It has another overwhelming benefit:  it exists TODAY as a commercial
product with the support of Bill Hawes, ace programmer!  This alone
carries great weight with me, a commercial developer with a commercial
product longing for this type of interprocess communication and data
transfer.

It is more than longing, though;  the code to support ARexx is going
into Microfiche Filer II even as we speak!


      My challenge is this:

Let's assume in this message thread that Arexx is the low and medium
level message passing standard.  It already exists and is, in fact,
being used in several commercial products already.

      SO LET'S DESIGN A HIGH LEVEL STANDARD!

A few definitions:

MACRO - an ARexx program that can invoke other macros or communicate
        with programs.

PROGRAM - a piece of software that has opened some rexx message ports,
          can invoke macros and can perhaps act as a server.

In the rexx system, communication is not symmetrical.  Programs can
invoke macros and macros can command programs.  However, programs cannot
command macros (other than by passing parameters upon startup or by
responding to a message from the macro).

A message sent from a macro is synchronous.  The macro does not regain
control until the program has responded.

A message sent from a program invoking a macro is asynchronous.  The
program may go on doing anything it pleases until it receives a message
from the macro or until the original message is replied.

However, in the rexx interface of Microfiche Filer, I have found it
to be advantageous to deal with macros in two ways: as a server (handling
single harmless requests from macros immediately), and as a synchronous
slave (by invoking a macro and allowing no input except USER ABORT and
macro commands until the macro has completed it's task).

Nearly all commands currently accepted by Microfiche Filer are atomic;
they complete their task and return immediately with the result or
an error code.  Several notable exceptions are "DISPLAY", "REQUEST", and
"STRING_REQUEST", which ask for user input, and the printing commands.

Simple YES/NO type information is returned as an error code, simple
string information is returned using rexx's RESULT string handling,
but the most interesting information is passed around in compound
variables.

Compound variables are able to contain groups of information, similar
to structures and arrays.  This information can be passed between
programs and macros with a single reference.

Well...This is getting quite long.  Let's just leave off here and see
what you have to say about this, so far.

Remember...Everything described here is already working in Microfiche
Filer II...So let's discuss not whether it's feasable or how efficient
it is, but how it can be used in interesting ways!


	cu,
	Gary

kim@amdahl.uts.amdahl.com (Kim DeVaughn) (04/01/88)

In article <8647@eddie.MIT.EDU>, gary@eddie.MIT.EDU (Gary Samad) writes:
> I would like to point out that there already exists a low and medium
> level standard that is sufficiently powerful to mediate conversations
> between applications and provide control mechanisms - AREXX!  ARexx may not
> be THE perfect solution (I personally have some problems with the
> language syntax), but it does meet the 'sufficiently powerful' test
> by being fully programmable and allowing the passing of ANY data in
> ANY format between concurrently running applications.
>
> It has another overwhelming benefit:  it exists TODAY as a commercial
> product with the support of Bill Hawes, ace programmer!  This alone
> carries great weight with me, a commercial developer with a commercial
> product longing for this type of interprocess communication and data
> transfer.

Exactly.


> It is more than longing, though;  the code to support ARexx is going
> into Microfiche Filer II even as we speak!

Glad to hear it!


> [ ... ]
>
> In the rexx system, communication is not symmetrical.  Programs can
> invoke macros and macros can command programs.  However, programs cannot
> command macros (other than by passing parameters upon startup or by
> responding to a message from the macro).

Ah, but they *can* control further execution of the macro with a well thought
out return-code/error-code handling strategy (as you mention later in your
posting).  I simply want to amplify what you said a little ...

In addition to passing a simple return-code back to the macro (which is often
all that's needed for processing control), the host program can also be
instructed to pass back result *string*.  This allows even greater flexibility
and a more sophisticated level of control of subsequent macro execution.

This can be accomplished via the RXFB_RESULT modifier bit in the command code,
with the host program then returning a pointer to an ArgString in rm_Result2.

Naturally, all this must be thought about ahead of time, and must be designed
into the system in the first place.  This is why error/exception/result processing,
and reporting is so fundementally important to take full advantage of the ARexx
interface.

/kim


-- 
UUCP:  kim@amdahl.amdahl.com
  or:  {sun,decwrl,hplabs,pyramid,ihnp4,uunet,oliveb,cbosgd,ames}!amdahl!kim
DDD:   408-746-8462
USPS:  Amdahl Corp.  M/S 249,  1250 E. Arques Av,  Sunnyvale, CA 94086
CIS:   76535,25

peter@nuchat.UUCP (Peter da Silva) (04/07/88)

In article <8647@eddie.MIT.EDU>, gary@eddie.MIT.EDU (Gary Samad) writes:
> The discussions have ranged from the highest levels to the lowest
> (and I must smile about the fact that some people were seriously examining
> the subject of FindPort being too slow, while the messages contained
> IFF format structures, the parsing of which would dwarf the time needed
> to do a FindPort! :-).

I must take exception to this statement. I am the originator of the current
IFF-based approach, and I'd like to point out that it does not require
any parsing whatsoever. It has an array of tagged pointers which can be
"parsed" in a few statements...

	for(i = 0; i < imsg->NumEntries; i++) {
		switch(imsg->IPCEntries[i].ie_Type) {
			case 'REXX':
				SendMsg(MyREXXPort, imsg->IPCEntries[i].ie_Ptr);
				imsg->IPCEntries[i].ie_Ptr = 0;
				break;
			case 'BMAP':
				DisplayBitMap(imsg->IPCEntries[i].ie_Ptr);
				break;
			...
		}
	}

Secondly, the HIGH-level IPC protocols for the machine already exist: namely
files, pipes, and clipboards. Rather than create a whole new namespace, let's
concentrate on tools to make that work better.

Finally, as I said before... I'd go for REXX if there was a freely re-
distributable dumb REXX server available. No, I'm not going to write
one... I've got enough on my plate already.
-- 
-- a clone of Peter (have you hugged your wolf today) da Silva  `-_-'
-- normally  ...!hoptoad!academ!uhnix1!sugar!peter                U
-- Disclaimer: These aren't mere opinions... these are *values*.

dillon@CORY.BERKELEY.EDU (Matt Dillon) (04/08/88)

>I must take exception to this statement. I am the originator of the current
>IFF-based approach, and I'd like to point out that it does not require
>any parsing whatsoever. It has an array of tagged pointers which can be
>"parsed" in a few statements...

	How do you represent a complete IFF structure?  With LIST's, CAT's
etc....  The idea is to have the IPC library handle the dirty work of doing
this.

				-Matt

doug@eris (Doug Merritt) (04/08/88)

In article <893@nuchat.UUCP> peter@nuchat.UUCP (Peter da Silva) writes:
>In article <8647@eddie.MIT.EDU>, gary@eddie.MIT.EDU (Gary Samad) writes:
>>
>> [...] IFF format structures, the parsing of which would dwarf the time
>> needed to do a FindPort! :-).
>
>I must take exception to this statement. I am the originator of the current
>IFF-based approach, and I'd like to point out that it does not require
>any parsing whatsoever. It has an array of tagged pointers which can be
> [...]
>			case 'REXX':

This is bad style...it is not guaranteed to work, according to K&R, and
certainly does *not* work with many C compilers. I don't know about Lattice
and Manx in particular, but even if they allow it now, they won't necessarily
allow it in the future. And there's a good chance that it won't work with
small model.  The standard way to specify long constants containing 4 ascii
characters is:
		(('R' << 24) | ('E' << 16) | ('X' << 8) | 'X')
or equivalently:
		#define	LONGCHRS(a,b,c,d) ((a<<24) | (b<<16) | (c<<8) | d)
		case LONGCHRS('R', 'E', 'X', 'X'):

This is still ugly, will still break *some* C compilers that can't quite
handle long constants in a switch, and furthermore counts on the compiler
being smart enough to create a hashed jump table; some C compilers are smart
enough to do that, some aren't. If they're not, then they'll produce code
that does a sequence of comparisons.  This point applies to the original
"case 'REXX':", too, btw.

Therefore the cleanest and fastest way (assuming that you're going to
check for more than a very few 4 byte constants) to do this is to create
a hashed array of the 4 byte strings, and do symbol table lookup,
returning a #defined constant that you then switch on:

#define	REXX	1	/* etc */
		switch(lookup(IffCode)) {
			case REXX:	[...]
			case ILBM:	[...]
		}

Note that the #defined constants will all be sequential integers, so
that the C compiler can create a very fast indexed jump table for this
(most C compilers have this optimization). Also note that it is possible,
if you work at it a little, to have it perform the lookup with a single
hash probe. The latter usually requires a fairly smart hash table
initializer, though, and generally people won't bother, so it could take
multiple probes. Note that the C compiler is highly unlikely to produce
code better than this with the original nonstandard construct "case 'REXX':",
because it's easier for people to optimize hashing than for a compiler to
do so.

Why do I nitpick? Because the rest of Peter's code was perfectly legitimate
C code (as opposed to psuedocode), which might lead people to say
"Hey, what a neat way to do that!", and we don't want to lead people
astray, now do we?

>Secondly, the HIGH-level IPC protocols for the machine already exist: namely
>files, pipes, and clipboards. Rather than create a whole new namespace, let's
>concentrate on tools to make that work better.

It's a very good idea to make good use of existing tools, but that does not
argue against using IPC. After all, IPC messages fit into the list
"files, pipes, and clipboards" as naturally as do the other members.

>Finally, as I said before... I'd go for REXX if there was a freely re-
>distributable dumb REXX server available. No, I'm not going to write
>one... I've got enough on my plate already.

Strongly agree. Any IPC standard therefore should not *count* on REXX.
But I think that's been pointed out several times before. Excuse me if
I've gotten confused about the current state of discussion.

	Doug Merritt		doug@mica.berkeley.edu (ucbvax!mica!doug)
			or	ucbvax!unisoft!certes!doug

	Doug Merritt		doug@mica.berkeley.edu (ucbvax!mica!doug)
			or	ucbvax!unisoft!certes!doug

gary@eddie.MIT.EDU (Gary Samad) (04/08/88)

In article <893@nuchat.UUCP> peter@nuchat.UUCP (Peter da Silva) writes:
}
}Secondly, the HIGH-level IPC protocols for the machine already exist: namely
}files, pipes, and clipboards. Rather than create a whole new namespace, let's
}concentrate on tools to make that work better.

Files, pipes, and clipboards are simply not as powerful as a full IPC
protocall.  None of them allow CONTROL of an application.  They only allow
DATA transfer.

}Finally, as I said before... I'd go for REXX if there was a freely re-
}distributable dumb REXX server available. No, I'm not going to write
}one... I've got enough on my plate already.

Cmon.  REXX only costs 50 bucks.  And it's a real commercial product.
A tool of this sophistication requires commercial support to be widely
accepted.  Especially by commercial developers.

A dumb REXX server is an oxymoron.  The beauty of REXX is that SOMEONE in
the IPC system has to be smart, and REXX is that someone.
That means that programs that use REXX can be brought up extremely 
easily and quickly.  It took only two weeks to provide FULL rexx support 
in Microfiche Filer.  And this includes 27 sophisticated commands, 
a safe asynchronous user abort mechanism, as well as the time to learn REXX!

	cu,
	Gary

peter@sugar.UUCP (Peter da Silva) (04/10/88)

In article ... dillon@CORY.BERKELEY.EDU.UUCP writes:
> >I must take exception to this statement. I am the originator of the current
> >IFF-based approach, and I'd like to point out that it does not require
> >any parsing whatsoever. It has an array of tagged pointers which can be
> >"parsed" in a few statements...

> 	How do you represent a complete IFF structure?  With LIST's, CAT's
> etc....  The idea is to have the IPC library handle the dirty work of doing
> this.

I *don't* represent a complete IFF structure. All I'm taking from IFF is the
4-byte "packed" ids. I suppose I could define a 'MORE' item that points to
another Item array, but I'm not sure why you'd want to.

One of the advantages of IFF is that if you don't understand a chunk, you
can ignore it. Similarly, if you don't understand a tag in an Item array
you can ignore it and go on to the next one.

	...
	default: break;
	...
-- 
-- Peter da Silva  `-_-'  ...!hoptoad!academ!uhnix1!sugar!peter
-- Disclaimer: These U aren't mere opinions... these are *values*.