See (p3,cmdlang) for something currently available.
{arcane}{nonref}Command Language Interpreter: A Preliminary Modularization. Some ideas on the structure of a command language for Gnosis. The command language will consist of the following components:
Its inputs are a CML like definition of the commands, and a terminal capability.
Its output is a complete command as will be acceptable to the command language interpreter. This output may be routed directly to the command language interpreter or to a file while building command files.
I think that the factory is merely another facility available via the CLI. The CLI should know nothing special about factories.
It is determined that we need to "make using the factory easier than not using it" {seat belts?}.
Begin (yet another) programming language in the language,
Make the CLI a sub-language of an existing {good} language.
Commands recognized by the command system are in the following distinct flavors:
Needs
Another possible definition of "command language" is a language in which to instruct the system what jobs you want it to do and when.
Informing the system of what to do for you during the coming evening is really programming. Typically such programs are simple and it is important to get the instructions right, as the consequences of an error might set some project back a day. All of the needs of general programming are present but the emphasis is different. The only differences that I can see, however, is that performance is unimportant and clarity is extra important(?).
In traditional command languages files are the most frequent operands and programs fetched from files are the most frequent operators. I believe that keys will play the role of files in this regard in Gnosis.
A language in which programs are very easy to debug
The task is to build a spell checker from a few simple components and to do so with the assurances that motivated the design of factories. We should also address the issues of space banks and meters.
We postulate the following components: Each of these programs consumes its input and produces its output according to the byte stream protocol. Each of these three programs are provided via factories.
A program SORT that reads a space-separated word list and sorts it and outputs the sorted list.
A program BOOL that reads two word lists and produces three sorted streams, one stream with the words that occur in both inputs and one stream for words in the first bit not the second and vice versa. The BOOL factory accepts its co-routine parameters, one at a time, along with an order code indicating which of its three outputs is required.
SORT_FACTORY(0,"#";IN,OUT==>c) produces a sorter of records that are delimited by "#" in the input stream and likewise on output.
BOOL_FACTORY(2;IN1,IN2,OUT==>c;) produces a unit that takes two lists and yields the list of words that are in the first list but not in the second list.
We wish to explain the meaning of "a^b^c" where the letters represent the creators of units with one input and one output. We consider "^" to be an associative binary operator. It is clear that the MODE of x^y must be the same as the MODE of x. Let us call this MODE UF for "unit factory".
According to our conventions an object of mode UF is a thing waiting for two co-gates upon receipt of which it will begin. Thus MODE UF = PROC(EXIT, EXIT)VOID.
MODE EXITPAIR = STRUCT(EXIT in, out); OP ^ = (UF left, right)UF: (EXIT a, b)VOID: (EXITPAIR ep = bscr #bscr is the byte stream creator.#; PAR BEGIN left(a, in OF ep), right(out OF ep, b) END)
PROC(EXIT in, out)VOID sort = SKIP #sort routine here#;
PROC(INT b, EXIT in1, in2, out)VOID bool = SKIP #bool routine here#;
PROC read file = (FILEKEY x)EXIT: SKIP #This routine produces a producing cogate for the file#;
PROC write file = (REF KEY out file key slot)EXIT: SKIP #return an consuming cogate that produces a file.#;
#The job! {with intermediate storage variables}#
PROC two arg bool = (EXIT a, b)VOID: bool(2,a,read file(#file-spec for spelling word list# SKIP), b);
PROC two arg parse = (EXIT a, b)VOID:
parse(",abcdefghijklmnopqrstuvwxyz",a,
b);
UF ultimate pipe = two arg parse ^ sort ^ two arg bool;
ultimate pipe(#file-spec for file to be checked# SKIP, sok key for terminal);
We should try to use existing language ideas and ideally an existing language.
Better yet we might find an interpreter that runs on the 370 that might be adapted to Gnosis. We list those interpreters for the 370 which we know of:
I have heard nothing of BRUIN for at least several years.
PLIC is slow at direct execution. I suspect that it would still be slow in Gnosis.
PL/I is a poor language for writing programs that are expected to run correctly the first time. It is not a simple language for the nonprofessional programmer. It is difficult to type constants in PL/I and the simplest use of a command language uses no variables, only constants.
FORTH is more a philosophy then a language. There are many languages that share the philosophy. Key areas of the philosophy:
There should be no extra overhead for checking such things as arithmetic overflow as the language itself allows you to re-define the operators to perform such checks.
Programs should be built in small units. {I have never seen a FORTH word definition take more then one 1024 byte "screen".}
Using the domain as the {only} subroutine construct.
We will also have a language in which we can construct simply the most powerful and must fundamental object in Gnosis -- a key to a domain with custom code inside.
The important point here is that a subroutine so constructed could be used not only in the context of other programs written in our interpretive language, but in any environment where keys may be invoked.
See (scope-rules) about connections between space bank problems and the scope problems of classical programming languages.
While programs using this feature are easy to construct they are frequently difficult to analyze. This may be a good trade-off here.
In the meantime we should have a direct execution language that has no macro facility, no conditionality, no arithmetic ability, no character substitution, but has a name space defined by a record collection, a command to invoke a key using key names as functions and arguments. Some facility is also necessary for constructing, passing, receiving and examining the data of key invocations.
Unless programming at all levels, and by this I mean from simple, throw-away programs to large, complex systems with hundreds of person years of effort and large budgets, is made as easy as possible, I believe that Gnosis will fail. We have a number of professional languages for large, complex systems, e.g., Pascal, PL/I, FORTRAN, COBOL etc. What we lack are languages that make combining existing function in novel ways easy. EXEC and the UNIX(r) shell have gone a long way beyond what these professional languages have done in making it simple to combine things. We should not make the mistake of thinking that one language can do everything.
One way to look at the command language problem is to ask "How can we make creator construction and invocation easy?" However, doing everything as gate jumps has the problem that people can't do gate jumps directly. They must use some language to instruct the system. The next thing they want to do is combine the facilities of that language to build custom constructs. A good example is receiving the Adventure application. It currently takes 5 or 10 CL1 commands, where the only real information the user needs to present is "Install Adventure, the transfer mechanism password is 'xxxx'." Commands files would solve this particular problem.
I would prefer to support the programming-like functions of the CMS exec language by writing PL/I programs and making sure that small jobs, so expressed, are truly small. By small I mean:
Not more than two pages and 10 nodes in the resulting "compiled object".
Not more than 1000 gate jumps in the creation of the object, including the editing, compilation, etc.
Not more than 20 gate jumps of overhead in the execution.
Not more than an editing session and a single command to create the object.
Proxies may talk to programmers in terms of the capabilities that they hold for the programmer. Proxies may talk to reservation agents about reservations.
CLI's are also likely to be tailored for terminal types.
See (screen).
Of the three ways of de-allocating storage {(p3,garbage)} programming languages have used all three.
Current Art
The EXEC language in CMS is easy to use and subroutines therein are represented as separate files. This means that after several years of use one's directory holds hundreds of routines in the form of files and there are no tools to help the user remember which routines indirectly support what functions. CMS thus puts the burden on the user without giving him the tools to do the job.
Algol-68 gives the programmer two choices when allocating new {core} storage, with one choice, storage is freed as the current block is exited. With the other, storage stays until the "end of the job" unless garbage collection can manage to free it. This is obviously a compromise leaning toward what is easily implemented rather than what is needed.
Some of the fixed commands that I can think of are: Jump to another directory, Logout, Show directory, Delete directory entry,
Of the domain packaged commands a pervasive problem is whether the command system is responsible for remembering whether such a command is discreet. Whether, indeed, such commands have their own memory.
Some of the people involved with the DOD security process have expressed the idea of a proxy that would help the user sort out what information was allowed where. We are not here talking about the proxy being the policeman, but merely the policeman's assistant. This need is over and beyond the "absolute need" for mandatory security.
Of the commands of our current system {(p3,com)} lets see which ones cause any problems and what the form of the mold should be:
The key designated by keyname2 is passed as a key parameter and the returned key would be installed in the user's directory as filename1.
You can not greatly improve on the general command style key call to improve the syntax of calling AUXDEF.
I would replace this command with two, one for get and one for send. Then the general command style key call does fine again.
Do we support the CMS function of producing a new file?
And then the old issue of a conversational program.
The general call syntax should make manifest which names provide keys to send and which provide names for returned keys.
Provisions must be made for conversations with talkative and inquisitive commands such as DDT in DEBUG.