\documentstyle[a4,12pt]{article}
\begin{document}
\author{Hamish Dewar}
\title{PAM: Parameter Acquisition Module}
\maketitle
\parskip .1 in
\setcounter{secnumdepth}{10}
\parindent 0in
\section{Preamble}
PAM: Parameter Acquisition Module - Hamish Dewar March 1984

Description

PAM is a set of procedures which may be called by programs to acquire parameters.
For the background to the approach, see the section "Getting Command Parameters
into Programs". The module is available for IMP programs on Vax/VMS and the APMs.

\section{Specifications}
On ECSVAX/VMS the relevant specifications for inclusion in programs
are available in:

\hspace*{ 2.1 in} IMP\_INCLUDE:PAM.INC

and the implementation module for linking is available in:

\hspace*{ 2.1 in} IMP\_INCLUDE:PAM.OBJ

On the APM system, the relevant specifications for inclusion in
programs are contained in the general-purpose file:

\hspace*{ 2.1 in} I:UTIL.INC

and the implementation modules are pre-installed.

As well as the procedures described in the following sections, the include
files specify:


\hspace*{ 0.4 in} the string function CLI PARAM which is the standard means
\\ \hspace*{ 0.4 in} of obtaining from the environment the parameter string
\\ \hspace*{ 0.4 in} from the command line invoking the program;

\hspace*{ 0.4 in} the record map PAM which is used to determine
\\ \hspace*{ 0.4 in} PAM\_GROUPSEP and PAM\_KEYFLAG -- the user's choice of
\\ \hspace*{ 0.4 in} separator characters;

\hspace*{ 0.4 in} the constant definitions for the values of FLAG attributes
\\ \hspace*{ 0.4 in} described below -- these all have the prefix PAM
\\ \hspace*{ 0.4 in} to avoid possible identifier clashes, so that,
\\ \hspace*{ 0.4 in} for example, the attribute cited below as INFILE is
\\ \hspace*{ 0.4 in} actually defined as PAM INFILE.

\section{Parameter types}

The definition procedures distinguish four general types:

\hspace*{ 0.3 in} integer

\hspace*{ 0.3 in} enumeration

\hspace*{ 0.3 in} string -- covering also input and output files

\hspace*{ 0.3 in} sets of Booleans -- a specialised requirement

\section{Mode of use}

In order to acquire its parameter values, a program requires to
execute the following steps:

\hspace*{ 0.3 in} call the appropriate definition procedure for each parameter in turn

\hspace*{ 0.3 in} call the parameter processing procedure

\section{Example of Use}

Suppose that a program has two input files, one output file, two
numeric parameters and a three-way diagnostic option.
The relevant declarations in the program might be.

\small \tt       \%ownstring (255)  MAIN                   \{design to be plotted\}, \\
                        PREDEF="PLOTPREDEF"    \{pre-definition file\}, \\
                        RESULTS="STANDOUT"     \{analysis of design\}, \\
      \%owninteger       MAX=8                  \{max number of levels\}, \\
                        ITER=5                 \{iterations\}, \\
      \%ownbyte          DIAG=0                 \{diagnostic option\} \\
                                               \{0:none, 1:brief: 2:full\} \\
\rm \normalsize The parameters for this program could be acquired by the following
sequence of calls:

\hspace*{ 0.3 in} define param("MAIN -- design to be plotted", main, infile+nodefault)
\\ \hspace*{ 0.3 in} define param("PREdef", predef, infile)
\\ \hspace*{ 0.3 in} define param("RESults", results, outfile)
\\ \hspace*{ 0.3 in} define int param("MAX -- max number of levels", max, newgroup)
\\ \hspace*{ 0.3 in} define int param("ITERations", iter, 0)
\\ \hspace*{ 0.3 in} define enum param("NONE,BRIEF,FULL -- diagnostics", diag, 0)
\\ \hspace*{ 0.3 in} process parameters(cliparam)

\section{Parameter definition}

There are three main procedures for defining parameters:

\hspace*{ 0.3 in} \%routine DEFINE PARAM (\%string(255) text, \%string(*)\%name variable, \%integer flags)
\\ \hspace*{ 0.4 in} -- to define string parameters

\hspace*{ 0.3 in} \%routine DEFINE INT PARAM (\%string(255) text, \%integername variable, \%integer flags)
\\ \hspace*{ 0.4 in} -- to define integer parameters

\hspace*{ 0.3 in} \%routine DEFINE ENUM PARAM(\%string(255) text, \%bytename variable, \%integer flags)
\\ \hspace*{ 0.4 in} -- to define enumeration parameters


The significance of the three arguments to the DEFINE procedures
is as follows:
\subsection{TEXT}
defines the keyword or keywords for the parameter, and
optionally provides an expanded explanation of its
significance. Keywords should be sequences of letters
only and the convention is adopted that acceptable initial
abbreviations are given in upper-case, optional trailing parts
in lower-case.
The expanded explanation should be separated from the keyword(s)
by at least one space.

In the case of an enumeration, there are a number of
keywords separated by commas (NB no spaces).
The keywords given correspond to the values
0,1,... in the order of presentation.

\subsection{VARIABLE}
specifies the program variable corresponding to the parameter.
This should always be an \%own variable.

For string parameters, it must be a string variable of any appropriate
length;

For integer parameters it must be a full integer;

For enumerations it must be a byte integer.
\subsubsection{FLAGS}
specifies the set of additional attributes for
the parameter. The attributes which may be specified are:

NODEFAULT: \hspace{ 0.3 in} indicates that there is no default value for this particular
\\ \hspace*{ 0.3 in} parameter -- causes interactive acquisition if no value
\\ \hspace*{ 0.3 in} is provided in the parameter string;

MAJOR: \hspace{ 0.3 in} indicates that this is an important parameter, for use
\\ \hspace*{ 0.3 in} in determining which parameters should be made visible
\\ \hspace*{ 0.3 in} to the casual enquirer

NEWGROUP: \hspace{ 0.3 in} indicates that if the value for this parameter is presented
\\ \hspace*{ 0.3 in} positionally within a parameter string, it must be preceded
\\ \hspace*{ 0.3 in} by a group separator character (typically used to segregate
\\ \hspace*{ 0.3 in} output file-names from input file-names);

INFILE: \hspace{ 0.3 in} for a string parameter, indicates that the value is an input
\\ \hspace*{ 0.3 in} file-name to be opened at the time of parameter acquisition;
\\ \hspace*{ 0.3 in} input stream numbers are used in sequence starting from 1;
\\ \hspace*{ 0.3 in} any failure to open the file causes an alternative name to
\\ \hspace*{ 0.3 in} be requested interactively.

OUTFILE: \hspace{ 0.3 in} for a string parameter, indicates that the value is an output
\\ \hspace*{ 0.2 in} file-name to be opened at the time of parameter acquisition;
\\ \hspace*{ 0.2 in} output stream numbers are used in sequence starting from 1;
\\ \hspace*{ 0.2 in} the first defined OUTFILE parameter implies NEWGROUP;
\\ \hspace*{ 0.2 in} any failure to open the file causes an alternative name to
\\ \hspace*{ 0.2 in} be requested interactively.

KEEPCASE: \hspace{ 0.3 in} by default, letters occurring in string parameters are
\\ \hspace*{ 0.2 in} standardised to upper-case; KEEPCASE disables this translation.


\subsection{Sets of Booleans}

There is an additional definition procedure for the specialised
case of sets of binary-valued options which are required to be
held internally as bits within a single word.
This is:

\hspace*{ 0.3 in} \%routine DEFINE BOOLEAN PARAMS (\%string(255) text, \%integername variable, \%integer flags)

In this case, the text component should start with a sequence
of comma-separated names, similar to an enumeration. However,
each of these names is treated as an individual binary enumeration,
using the prefix 'NO' to derive the negated case.
For example, the set LIST,CHECK is treated as two enumerations
(NOLIST,LIST) and (NOCHECK,CHECK). For this case VARIABLE should be
a full integer, and bits are assigned in sequence starting from the
more significant end (null names may be used to pad).


\section{Acquiring parameter values}

After defining the types of the parameters in sequence, a single
procedure call is made to the procedure PROCESS PARAMETERS.
This procedure takes as argument a single string
which it processes to yield values for assignment to the relevant
parameters.
Typically this string will be derived from the standard function
CLI PARAM which makes available to a program the parameter string
from the command line invoking it.
PROCESS PARAMETERS
should be called immediately after the last definition has been set up and it
can be used once only for any set of definitions.

\section{Errors}

When a localised error is discovered in a parameter string,
the user is given the opportunity to correct the mistake interactively.
Where this is not feasible or if the program is not being run interactively,
a report is made and the program stops.

\section{User appearance}

The conventions applied to the processing of the parameter string
are as follows. Parameter values for string or numeric parameters
may be presented positionally or by keyword selection. Enumerated
type parameters may be presented by keyword selection only.
Keyword selection is indicated by the appearance of a keyword flag
character immediately followed by a letter; the character '-' (minus)
is always honoured as a keyword flag character, as is the user's
chosen alternative if there is one. The former should be used to achieve
independence of user choice.
In the case of string or numeric parameters, the keyword must be
followed by an equals sign and a value of the appropriate type
(eg -OUTFILE=TEMP2 or -CASES=20);
in the case of enumerations, the keyword itself indicates the value
(eg -FULL).

Positional parameters within any group are separated by commas;
any parameter defined with the attribute NEWGROUP requires that the
value should instead be preceded by a group separator character,
as chosen by the user.

If the parameter string consists of, or is terminated by, one or two
query symbols ('?'), this is interpreted as a request to enter
interactive mode, displaying to the user all (two queries) or the major (one
query) parameters and their default values (or values assigned thus far)
and permitting additional values to be specified.

The facility for the user to specify an individual choice for certain
separator symbols is exercised on ECSVAX/VMS by
providing an alternative definition for the symbol PAM\_INFO. This should
be a two-character definition: group separator followed by keyword flag.
For example, to select space as the group separator and '!' as the keyword
flag the definition would be:

\hspace*{ 1.9 in} DEFINE PAM\_INFO " !

Note the use of the double-quote immediately before the two charcters.
On the APM, the command PAMSET is used and expects as data the
group separator followed by the keyword flag.
Space is not a valid choice for keyword flag, nor dash (minus) for
group separator, and there are a number of other characters which would not
be sensible for either, depending on the syntax of file-names on the
particular system.

\section{Limitations}

Some of the details of this facility are provisional and suggestions
for improvement are welcome. The existing implementation of
interactive enquiry about, and acquisition of, parameters is limited,
and will surely be extended and varied; this should not, however,
perturb the way in which programs interface to the module.

The module seeks to cover the most common requirements in terms of
types and defaults, and to leave the way open for other cases
to be handled by the program itself. Thus it is fully recognised
that the INFILE/OUTFILE attributes will not deal with cases where
it is inappropriate to open files at the outset, or where names
have to be derived by more complex procedures, or where the mode of
access is non-standard. It would be desirable to cover a few more
cases automatically, such as default extensions, and suggestions
in this area would be particularly welcome.

Note that, for consistency of user appearance,
the first parameter corresponding to an output file-name
should be given the attribute
NEWGROUP, even if it is not designated OUTFILE.

There are also quite a few detailed points about 'syntax' which
will require to be refined on a pragmatic basis.

The module does not include provision for acquiring values of type
real. There is no problem in principle in extending it to do so,
but it seems best to be conservative
about what is supported at such a basic level.

At present on the APM implementation there is no checking on
the validity of string lengths.
Also at present the module does not distinguish interactive execution
from non-interactive.


\section{Getting Command Parameters into Programs}

\section{Axioms}
\small \tt 1.     The definition of \%what the parameters of a program are \\
       should be independent of the specification of \%how they are acquired. \\

2.1    The proper place for definition of what the parameters \\
       are is within the program. \\

2.2    The proper place for specification of how the parameters \\
       are to be acquired is not in the program. \\

3.     There should be a variety of different ways for furnishing \\
       values for parameters, provided by different user interfaces and reflecting \\
       different user preferences. \\

4.     The methods for specifying parameter values provided by a system \\
       should be applicable to all programming languages supported on the system. \\

5.     As well as providing ways of communicating parameter values \\
       from user to program, there needs also to be communication to the user \\
       of information about the parameters of a program (or, more precisely, \\
       a command): their names, significance and default values. \\

6.1    The form of parameter definition within programs should be \\
       supportable on a variety of systems. \\

6.2    The form of parameter definition within programs should \\
       be consistent with the possibility of eventual compiler support. \\
\rm \normalsize 
\section{Consequences of the axioms}

Axioms 1 to 3 are incompatible with the philosophy of
such command languages as the VAX/VMS
DCL, in which the definition of what the parameters for a command are
is inextricably bound up with the form and order of presentation
of these parameters in a conventional command language.

It is clearly advantageous if the requirement imposed by Axiom 5
can be handled within the same mechanism as used for parameter acquisition,
though this may be difficult to achieve.

Axioms 4 and
6.1 are at odds with an approach which pre-supposes that programs
are 'called' with typed parameters as for procedure calls, attractive
though this would be in many ways.

Axiom 6.2 stems from 2.1. The justification for 2.1 is that the definition
of the parameters to a program, their types and possible ranges, is as
much a part of the definition of what the program does as the
instructions it contains. If this is so, we should expect it eventually
to be reflected in the language definition, which makes it sensible
to design forms of definition, and accept principles of usage,
which are consistent with this assumption.

\section{Status of parameters}

One obvious implication of the considerations just mentioned
is that parameters may be expected to be individual global variables
within programs.
So we postulate that there should be a way of designating as
parameters a subset of the global variables declared in a program,
just as another such group might be designated as volatile variables.

One natural thought is to
regard parameters as nothing more than externals -- data to be supplied
from outside the program itself. There are both logical and practical
difficulties to identifying parameters with externals.
External variables, though not (necessarily)
volatile, may have their values altered by arbitrary external procedure calls,
whereas the concept of a parameter is that of a variable which may
be initialised to an externally provided value, but is not otherwise
capable of being altered from outside the program. In any case, external data
does not provide useful flexibilty in systems which do not support
dynamic external linkage.

Accordingly, parameter-hood must be regarded as a distinct status.
Since existing languages do not in general recognise the concept,
it is necessary to introduce it, either by language extension or
by a technique of informal language extension using stylised comments.
This applies to other attributes of parameters as well.

\section{Attributes of parameters}

The members of any group of variables are necessarily presented in a certain
order;
it is open to make use of this to provide a positional significance,
as well as keyword identification, in a command language.

As variables, parameters would be typed.
Axiom 4, however, imposes a restriction on the over-enthusiastic use
of esoteric type mechanisms. At least the following three cases seem
indispensable:

\hspace*{ 1.1 in} integer (preferably with range specification)

\hspace*{ 1.1 in} enumerated type (individually named cases)

\hspace*{ 1.1 in} string

\section{Integers}

For this case, the user interface must provide
a convenient means for the user to supply arbitrary integer values,
and the acquisition mechanism should check that these values are within
the relevant range.
In a conventional command language, the form of presentation would
typically take a form such as:

\hspace*{ 1.1 in} MAX=1000

The pre-requisites for support within source language programs
are: variables of type integer; range specification; initialisation
option to provide default value.

\section{Enumerations}

At first sight, Boolean variables would appear to be the appropriate way
to handle binary choices, with the typical form of presentation
for a Boolean option LIST, say, being:
\\ \hspace*{ 1.1 in} LIST or NOLIST
However, enumerated types provide a more flexible means of handling
both binary and multiple choices.
Given the declaration of a parameter V of an enumerated type with
constant identifiers THIS, THAT and TOTHER, one possible form of specification,
following the pattern of the integer case, would be:
\\ \hspace*{ 0.6 in} V=THIS \hspace{ 0.2 in} or \hspace{ 0.2 in} V=THAT \hspace{ 0.2 in} or \hspace{ 0.2 in} V=TOTHER
However, if there is only one parameter of that type, the constant
identifiers themselves should suffice:
\\ \hspace*{ 0.7 in} THIS \hspace{ 0.3 in} or \hspace{ 0.2 in} THAT \hspace{ 0.2 in} or \hspace{ 0.2 in} TOTHER

It is suggested that user convenience is probably best served by
accepting the constraint that all enumerated-type parameters should
be of different types, so that the second form is the only one that
needs to be used.

It is also suggested that Boolean options should simply be treated
as special cases of enumerations, as, for example, (NOLIST,LIST) or
(NOPLOT,PLOT).

\section{Strings}

If string parameters were only used to convey pieces of text
for use as, say, headings, they would be as straightforward
as the first two types considered. They raise distinct problems
by virtue of their use to specify the files or other streams
to be operated on by a program.

The root of the problem that this consideration creates is the
issue of file-names versus files. In the case of
an integer parameter, the user types a sequence of digits, and we
expect the program to receive an object of integer type which is the appropriate
internal representation of that sequence.
It would remove a number of problems if the same treatment could be
applied to files, so that there would be parameters of various file types
which would be initialised to appropriate files by an externally
applied process of referencing the name supplied by the user.

The main problem with this approach is that it leads to over early binding,
which
eliminates the possibility of applying various systematic operations or
substitutions
to file-names within the program. To achieve such effects, we are obliged to
operate
with file-names rather than files, with the consequence of importing
into programs objects which are highly system dependent,
and complicating a number of aspects of parameter acquisition and
defaulting.

However, it should be possible to handle at least the most
straightforward cases of input and output streams automatically.

\section{Defaults}

As noted earlier, the use of an initialisation statement in the
program may be quite a reasonable way of providing a default value
for a simple parameter.
However, as well as any long-stop defaults built into the program
there is also a need to provide a way of defining commands which
call that program with alternative defaults.
Such layered defaulting can be supported reasonably well in
a command language such as that on VMS
in which a new command can be defined as the application of a
partial parameter string to an existing command.
With this approach, it is important that the ultimate parameter
string is interpreted sequentially, so that user supplied values
over-ride the defaults.
It is less easy to see how this requirement can be integrated with an
environment
providing interactive parameter acquisition, though it may not
be impossible to do so.

More attractive for some purposes is to
have the possibility of specifying the default value as some
external or environmental \%variable.

A separate difficulty attaches to the use of string parameters
for file-names. Including explicit default values for these in a program
immediately compromises its portability across systems.
The use of an external or environmental variable would avoid this
difficulty, but if the system supports symbolic name substitution
at the point of file reference, it is probably best handled
by having a symbolic name as the default.

\section{Implementation approaches}

At the low level, the implementation will have to be in terms
of procedure calls out of the program to a parameter acquisition
module. It would be preferable to be able to access the parameter
definitions of a program in a static fashion from outside, so that
this information would be in the same category as linkage
information, but this is ruled out by Axioms 4 and 6.1.

Three means of deriving the low level implementation are
relevant:

\hspace*{ 0.6 in} Compilation: where the language and implementation support
\\ \hspace*{ 1.5 in} all the required apparatus

\hspace*{ 0.6 in} Translation: to convert a program with part of the information
\\ \hspace*{ 1.5 in} conveyed by language features and part by
\\ \hspace*{ 1.5 in} stylised comments to a form suitable for execution

\hspace*{ 0.6 in} Programming: direct use of the low level facilities
\\ \hspace*{ 1.5 in} (only as a last resort).

\section{Low level interface}

It would be attractive to present all the information about
parameters in one go, but this would put an excessive strain
on the type mechanisms of most languages, so that an approach
involving one call per parameter is indicated. The parameter
acquisition module on the other side of the interface could
simply implement these sequentially, but full flexibility
(of enquiry as well as acquisition)
requires that they should be cumulated until all are available.
(This may involve some jiggery-pokery behind the scenes, which
is one reason why automatic generation of the call sequences
is desirable).

Accordingly the interface would provide:

\hspace*{ 0.4 in} a limited set of procedures for defining parameters
\\ \hspace*{ 0.4 in} of different types, one parameter defined by each
\\ \hspace*{ 0.4 in} call and the order of the calls determining the
\\ \hspace*{ 0.4 in} positional significance of the parameters;

\hspace*{ 0.4 in} one procedure with a parameter string as argument
\\ \hspace*{ 0.4 in} to process the parameter string in the light of the
\\ \hspace*{ 0.4 in} previously executed definitions and/or to interact
\\ \hspace*{ 0.4 in} with the user to inform about and/or acquire parameters.

\vspace{.75in} view:pam printed on 10/02/89 at 17.44

\newpage
\tableofcontents
\end{document}
