Like most large computer users, the United States Department of Defense has been plagued with a
proliferation of high order languages and incompatible systems serving the "same" language.
The DoD's problems are, in principal, no different from the rest of the computer user community;
they are simply larger as is the use of computers. Further, DoD systems are often individually
very large and very long lived. Because of the intimate integration of the computer resources
with the rest of a large defense system, it has not been possible to change computer subsystems
with the frequency which might characterize a commercial operation. As a result, maintenance
of the computer system is both long term and dynamic, and maintenance in many casses involves
modification of the system to respond to new threats. Defense systems are often composed of
interacting but independently developed subsystems, sometimes brought into existence over a
period of years, all of which must be served by a common but evolving hardware base. In such
an environment, the Department of Defense finds itself spending an increasingly larger fraction
of its systems resources on software. High order language commonality and the resulting flexibility
would provide a powerful tool for reducing the high cost of software in the DoD.
With each of the military departments studying this problem and making proposals for common languages,
it was clear that the greatest benefit could be reaped by providing languages common across the Department of Defense. In January 1975, a DoD High Order Language Working Group (HOLWG) was chartered by DDR&E with representatives from the Military Departments to investigate the requirements and specifications for programming language commonality, to compare these with existing approaches, and to recommend adoption or implementation of the necessary common language or languages. Until the matter is resolved, the DoD will not support any further implementation of new high order languages in R&D programs.
The first task of the HOL working group was to formulate a set of requirements consistent with the
levies of the military departments. This effort proceeded as follows:
While there is no intent to replace the already standard COBOL and FORTRAN in their field of application,
initially there was no reason to unnecessarily restrict the requirements to only those areas such as
real-time applications or weapons systems where the major problems are, although this area must first
receive emphasis. Therefore, requirements were solicited from as broad a base as possible, to be
prioritized later as required. Further, inquiries were not restricted to those programs presently
using high order languages, rather, a major thrust of the effort is to provide HOL's to meet the
requirements of those who are now constrained to use an assembly language for lack of a suitable HOL.
A major problem was to formulate the inquiry in such a way that meaningful requirements would result.
On the one hand, one wishes to avoid broad generalities such as the obvious goals of efficiency,
ease of coding, readability, etc., which, while they are very real goals, are insufficiently quantified
to provide any detailed guidance. On the other hand, to over specify the requirements at the
level of individual language features would merely normalize past idiosyncrasies and magnify
distinctions which do not represent fundamental differences. It has proved to be impossible
to define rigorously the exact level requirement desired; and, therefore, a "Strawman" of
preliminary requirements was established to
define this level by illustration. The "strawman" was not intended to be complete or consistent, rather,
it was deliberately provacative in order to elicit the widest possible comment. It was forwarded to the Military Departments and,
by them, to their various operating organizations. In addition, it was distributed to other government agencies, to the academic
community, and to industry, through industry organizations and military contractors, and by direct inquiry.
A number of individuals outside the U.S. were also solicited for comments. Hundreds of individuals and organizations have had
an opportunity to examine this document and provide inputs, the bulk of such inputs were positive and useful. Negative
comments were almost universally based on a misunderstanding of the status of the document, believing this to purport to be a
complete and consistent set of requirements some pointed out that it was no such thing.
The results of four months of such input were put together in a more concrete form, one which could then
pretend to represent a fairly complete set of requirements, although still a tentative set. This document was called the "woodenman,"
and it too was distributed widely. It provided a more rigoroous framework for specific comment. On the basis
of all the inputs and the official responses from each of the Military Departments,
a more complete set of requirements had evolved and is presented here as a "tinman." This document represents
a set of requirements for a high order computer programming language consistent with the input from the Military Services.
A high order language (HOL) is one which provides compression of a computer program such that one HOL statement represents
many machine language instructions.
Experienced programmers in the early 50's found that they would generate similar instruction sequences
often enough that it proved
useful to either set aside duplicated blocks of cards to be inserted in the
program as required or, in a more automated fashion, to develop macros which
might be defined once to the assembly program and thereafter invoked by shorthand notation. From such
beginnings high order languages were evolved as a method for speeding up programming.
The extension and development of this technique led to the more powerful
concept of a higher level of programming language.
The first truly successful high order language was FORTRAN. It was developed for the IBM-704 and in the original version most
of its constructs were identical to those commonly employed by machine language programmers for that machine;
in some sense, it was inspired by this specific machine. But, in addition, the constructs were sufficiently
general that it could be adapted fairly easily to other machines, and the
practical reality emerged the first time of constructing
a program which was machine independent, even across manufacturers.
So powerful was this concept at the time that in the early 60's the use of such
high order languages was heralded as automatic programming. (Annual Review of Automatic
Programming, Pergamon Press, Oxford, 1960, 1961, 1963, 1964, etc.)
In 1959 a meeting was held in the Pentagon to establish a common business-oriented language, the outcome
of which was COBOL (Programming Languges: History and Fundamentals, Jean E. Sammet, Prentice-Hall, Edgewood Cliffs, N.J. 1969).
Other similar attempts at fairly general languages such as ALGOL, as well as those designed for more
specialized users such as CMS-2 or JOVIAL have found their somewhat smaller niche in the marketplace.
Even higher level specialized languages have come into existence such as SIMSCRIPT,
for simulation programs, or ATLAS, for automatic test equipment.
There are problem-specific applications packages which may be generated through the use of one of the
other high order language programming languages and are not in the range of the present effort.
By high order language, this report will mean a computer programming language of the general level of COBOL
or FORTRAN, primarily designed for programmers to communicate with computers. It is non-problem specific and should be able
to exercise almost all of the capability normally used by those programming in machine language, and at
a reduction of an order of magnitude in the number of statements necessary. The language is relatively
machine independent, representing possible logical constructs rather than specific hardware function, and is
translated by a compiler into machine code to be run on a target machine.
III. GENERAL GOALS
In this section are listed the general goals of a DoD software program. Some of the ways in which these impact
on the detailed desired language characteristics set out in the next section
There is no real attempt to order or weight these goals at this
point, nor is there any claim that the list is complete. It is merely a very brief summary of discussions
taking place during the evolution of the requirements.
The overriding goal of all technology and standardization programs are to reduce the cost of Defense systems.
Software is an area in which there are great opportunities in cost savings which can be brought about through
actions of the DoD. Computer hardware savings are much more difficult to generate. Since the Department of
Defense represents only a very small fraction of the computer hardware market, it must effectively content itself with the off-shoots
of the mainstream of computer technology. On the other hand, the DoD is the main customer
for software; and the major support for basic computer science and technology. It is, therefore, in a position to influence
the state-of-the-art and to materially change the software development process. A number of managerial
initiatives to this end are presently under development. Many of them, including the setting up of libraries for software exchange,
building up of a tool environment for improved software production facilities, distribution of government furnished tools,
encourage of the use of high order languages for maintenance ease,
etc., depend upon, or will be facilitated by, restriction to a minimal number of common high order languages.
Much of each new software system is repetitive of processes that have been written before. A few new ideas may be added,
linkages may be changed, but the bulk of the work is not new. Yet most systems are
started from scratch with little dependence on previous work other than what the individual programmers might remember.
There is little high order language commonality. A new language or dialect, or at least an incompatible compiler,
is often generated for each project and it is impossible to sustain the creation of a truly powerful production
Facilities are often locked into one particular computer because of the great expense of transferring software to the new machine.
There are several proposals and on-going work in the DoD concerning the
facilities for the translation of software, just in a commercial-like environment.
This problem and its implications may
be far more serious in some of our more specialized applications. A fully supported and controlled
common language facility would eliminate most of these difficulties and provide
more flexibility to the managers to computer resources.
RESPONSIVENESS AND TIMELINESS
By its very nature, software is plagued with underestimates. It represents a major fraction of the total systems
capability, but is physically insignificant. There are no power requirements, no drop tests,
no critical materials consumed. It is basically unsubstantive, at best, a few bits on a magneteic tape.
It is by nature easy and quick to change and, by implication, it is difficult to imagine how it can be lengthy to
produce. While it is easy to change, it is sometimes very hard to make it correct, as opposed to just different.
As a result, estimates of the time to complete a project are often overly optimistic, sometimes so much so that the hardware is ready before
the software. The cost of such delays is not just the extra man hours to bring the software into shape,
but must be computed on the loss of the entire system during the period of delay. The technology then does
not exist for doing accurately estimating software schedules other than by experience and analogy.
Language can only contribute to this in that it is part of a stable software production environment.
An actual reduction in the time to produce software would be possible if the language reduced the coding time of the project.
The mere existence of the high order language normally reduces this coding time by a fair amount, and certain language features may act
to improve this. One must remember, however, that the coding portion of a large project normally represents
only ten or fifteen percent of the total time involved and the promotion of writing must, therefore, be weighted with other
portions of the program production cycle. A major fraction of this cycle, sometimes up to half, is involved with
debugging and checking and, therefore, the thrust to more reliable code must be stronger.
Specification and design is a similarly large fraction of the effort, and factors such as
modularity which simplify the design are also important. The overriding consideration must, however, be the possibility of
eliminating most of the effort altogether through reusing portions of both code and design which have been done before. The ability to draw upon large
amounts of past work, either through libraries, previous experience, or automatic programming tools, offer
the greatest possibility for payoff in timeliness and responsiveness.
It must be pointed out that this thrust towards transportability emphasizes language transportability because the elments to be
transported are individual subprograms and routines not necessarily systems concepts or coupling schemes. It is the lack of
acceptance of the possibility of using previously designed and certified piece parts which
separates present day hardware and software philosophy to the detriment of the latter.
Perhaps the most characteristically military requirement for DoD software is reliability.
While all gradations of this exist in the DoD, certainly the combination of extreme complexity
in systems, some almost untestable, and the life and death implications, not just of individuals but of
millions, must be unique. This reliability requirement is reflected in verification, validation, and certification during the
production process, as well as back-up in alternate systems, safeguards, etc.
A significant portion of the software cost is tied up in this thrust, although often very subtly. Language
characteristics which promote the production of reliable code must be weighted very highly.
Commonality allowing the reuse of previously well-certified blocks of code is also of importance. Unfortunately, the technology
does not exist to automatically prove the correctness of code at a useable level. Should it eventually be possible
to prove that a code will do exactly what it is intended to do and also, as in the security question, will
not do anything that is not intended, the language features which make
this possible should have very high priority in the DoD. Until then, perhaps the best we can do is make available the possibility
for investigation and experiments in this direction.
Other features promoting reliability in the DoD programming environment would be simplicity and unambiguity of the language
and readability of the constructs. It has been suggested that certain new programming techniques
inherently produce better and more reliable code. A language should
make it possible to use such techniques, although the brunt of enforcement must be on the programming management environment.
A major portion of defense cost in software systems occurs during the maintenance phase.
These systems are often very long lived, which is to be expected from their size and complexity and interaction with other
systems. They must be kept viable for upwards of twenty years during which time major changes can take place in the threat, the
employment concept, and even portions of the hardware. As a result, maintenance is
often a blanket for continued development and improvement. Over this period of time, the responsibility
for the program will pass through many hands both individually and corporately, between contractor and government
organizations. Over time and with each transition, knowledge is lost. The more readable
and definitive the program, the better knowledge will be transmitted. Transportability of the main program is
usually not a question in this phase, but transportability in
machine independence of the tools necessary to maintain and support that program
are vital as the facilities used in this maintenance will change much
more rapidly then will the main system hardware. Likewise, one of the main tools
is the personnel involved. Reduction of the total number of languages which they must work with will increase the efficiency
and the reliability of the maintenance effort. Documentation of all sorts is most important in this phase. Whatever
characteristics of the language that promote or support documentation, internal or external, will contribute to maintainability.
A certain amount of self-documentation results just from the use of a high order language. Modularity and structured
programming can further aid. All modern techniques in this area must be available.
Training is a difficult factor to quantify. Formal courses measure only a very small fraction
of the training that a programmer gets. The bulk of it is in the form of on-job-training or simply experience. In many
cases, for instance scientific programming, the training is woefully inadequate or even non-existent. The disparity
in the productivity
between programmers may, in many cases, be traced to inadequate training. Better than the productivity measure
would be the cost resulting from poorly written programs. Reduction of the number of
languages in use would simplify the training burden.
It might be argued, particularly by expert programmers, that transitioning to a new language is fairly
simple and should only take a few days of study and practice. They would then argue against paying any penalty.
Unfortunately, a census of the active programmers on DoD projects, whether in-house or contract, would uncover only a small minority of
such versatile experts. The average programmer is often tied to a single language and, at that, not completely
proficient in its techniques and tools.
The training burden would also argue for a simple language with a
minimum of unambiguous constructs. Ideally, the constructs would fail soft so that ignorance of a facility
would simply deny that facility and not result in unexpected side effects.
One of te two main technical advantages of high order languages in general is transportability, sometimes termed "machine independence." The advantage of
being able to write a program in sufficiently general form that it could be compiled on to more than one computer
is appealing for a number of reasons. One can transfer capabilities developed in one project to
another working on different equipment, and one can expect greater lifetime
for software when it can be carried on from one generation of machine to the next in the same installation.
Both of these advantages are clear cut and everyone with a few years of software
experience has their own examples to cite in this regard.
The language requirements associated with transportability depend on the situation. In the very early days of SHARE, the
only really large-scale computer was the 704 and a great deal of interchange took place for programs written with
fairly standard interfaces in machine language. This was entirely adequate for that time.
The prsent diversity of machines requires a different technique. The use of high order language and compiling down to machine
code makes a certain amount of machine independence possible but not necessarily inevitable.
Any good high order language should lend itself to efficient compilers for most any machine. With appropriate
linking mechanisms programs from
various languages could be put together as required. Unfortunately, the
practical world intervenes and the production of good compilers for every language and
every machine is not a reasonable expectation, nor is
sufficient familiarity on the part of a majority of programmers with a large number of languages.
To make the overall software environment relatively machine independent therefore requires a minimal number of high
order languages with reasonably general constructs and active support for wide availability of tools and compilers. This would
further suggest that high order language compilers written in that high order language would be most
One of the snares that has appeared in the past inhibiting transportability has been the occurrence of incompatible
implementations of a single high order language. A language might be insufficiently or ambiguously specified such that
different implementors making decisions in an uncontrolled fashion produce incompatible implementations.
Further, each one may have his own ideas for additions to the defined language or perhaps may invoke subsets leaving out
more difficult to implement or momentarily unnecessary features. We have examples of literally dozens of different
implementations of a single language. These are the cruelest mockery of language commality. Differences are
sometimes so subtle as to be difficult to find and lead to undiscovered catastrophes. Such experiences
give programmers an almost paranoid skepticism of claims of transportability. To make transportability a reality will, therefore,
require not only a rigid and unambiguous language specification, but control or dential of subsets and
supersets and rigorous certification of all implementations. It will further require
the widespread availability of such certified compilers for many machines.
The payoff from transportability could be enormous. Many programming chores are simply redoing things which have been done
before. Each project usually only adds a small fraction to the sum total of knowledge.
If it could draw upon past work, cost, timeliness and reliability would all be markedly improved. So far
from reality is this today that the techniques involving libraries, etc., have not been worked out.
A common high order language is simply one step,
albiet an important one, towards this goal.
The other major advantage initially claimed for high order languages was that they were easier to read and write, being closer
to natural language than is machine code. Claims in this direction were sometimes carried to an extreme and some were promoted
so highly that their advocates would have you believe that the coder need not know anything about the machine, simply write
out the requirements in English. History does not always support these claims. Many such languages advocated on this
basis now are the ones who have the most specialized programmers as their users. The DoD environment
is sufficiently large and specialized that the allocation of personnel specifically for software is the rule anyway and there is
no strong requirement to eliminate other specialists in this area. This is in contradistinction to a very small commercial firm
which may have insufficient demands to justify a fulltime programming staff.
Our requirement for readability and writability is therefore primarily among specialists. The desire to communicate with a computer
system in natural language is an entirely different one in the DoD and involves
query languages or applications programs outside the scope of
this high order language effort.
Readability is clearly more important to the DoD than writability. The program is written once, but may have to be read dozens
of times over a period of years for verification, modification, etc. This is certainly true of all weapons systems applications,
and even most of our scientific and simulation programs are very long lived. This requirement
is very much different from one which might be generated, for instance, in a university environment when a program may have
a life of only a few months and a single person working on it.
Ease of writing is not an inconsiderable goal but one which may be promoted through intelligent
terminals, preprocessors, interactive systems, etc. The language evaluation should favor readability where conflict arises.
Efficiency is probably the one overriding consideration on which high order languages stand or fall. Whether it be in runtime speed or
memory requirements, these quantifiable costs of using a high order language in preference
to machine language or assembly code is almost universally cited as the reason for rejecting HOL in a project. Often a detailed study of the matter is not
accomplished, so strong do feelings run on this subject. Many changes have taken place in the technology in recent years so as to reduce the importance
of this matter, but it is still such an emotion-charged issue that it must be recognized as the principle customer concern.
Much of the pressure that existed some years ago towards efficiency is no longer relevant. In former times the cost of memory
was such a large fraction of the total system expenditure that it might seem reasonable to sacrifice many other advantages
in order to obtain memory efficiency. This can no longer be said to be the case. Software,
particularly the maintenance portion, is becoming much more important than the hardware. Hardware costs
are falling at such a rate that the change in technology over just a few months can decrease the effective cost of
memory enough to offset any loss in efficiency, while the cost of going to machine code might result in a much longer delay in developing
the program. Likewise, in speed there is often a penalty to pay which is invariably judged so high, often on the basis of
experience with bad language implementations, that it is common folklore that "HOL cannot be used in real-time applications"
or that one must at least have the capability of dropping down into machine code for "time-critical" portions of the system.
Yet the cost of increasing the central processor hardware capability by some appropriate amount may be far less than the
software burden incurred.
While the cost arguments for HOL are valid, they do not take into account some
of the realities of system procurements. It has been common in the past that the hardware
configuration is determined very early
in the process and the software must be made to fit. Under these conditions, particularly
when life cycle cost is not an
effective control, there is little choice for the project manager
but to be driven to efficiency. A similar situation may arise in the later phases of system life when a new threat or other additional
burden must be accomodated within existing hardware.
What measures of efficiency are reasonable? Normally, one thinks in terms of a few tens of percent.
An implementation that
is within ten percent of assembly language code in speed of execution or memory occupied
would be difficult to distinguish. The differences
in the quality of code produced by even very good programmers is probably greater than this.
(In comparisons one only cites very good programmers. Many
current implementations may be as good as an average programmer.) A thirty percent penalty
might be appropriate in some situations and justified in a sufficiently detailed examination of all costs.
A fifty percent degradation for going to high order language would probably be unacceptable for any project in which the efficiency
of the project code was of significance. These figures may be overly severe from a strictly statistical view considering that
the logic of a code may admit to programmer variations much greater than these, and large improvements in speed efficiency must be sought there.
Nevertheless, there is no justification for adding on an additional excessive penalty, particularly when the high
order language can be very efficient. To illustrate that an HOL can be efficient, take as an extreme example the
technique of defining the program logic in a high order language which is then compiled by hand, a technique which has
proved useful in the early phases of some projects. Presumbably, the compilation in such a case should be very good.
One of the main difficulties with many existing high order languages is that their implementations have often been
poor, particularly languages generated for single projects and languages implemented in a short time with limited resources. It is not
suprising that the implementation is not as powerful as that which could be obtained if 10 or 100 times more
effort could be devoted to its development and to the tools and techniques for its use. Such powerful implementations
are very good and optimize better than the average programmer. Assuming a very minimal number of well-supported languages
for the Department of Defense, one could devote sufficient effort to provide the tools and compilers to produce very efficient
object code. It is not clear that any other language requirement mitigates against this expectation.
This particular requirement, or solution, would reinforce the thrust to commonality by making it attractive to reduce
not only the number of languages supported but a number of different compiler approaches and would call for the type of
control of the language which would promote large efforts for tools and compilers. A contributing technological trend
is for DoD programs, particularly those which are the most critical
real-time programs, to have available very large computers on which to build the system, even though it may
eventually run on a small computer. The large systems can
support cross compilers which are much more powerful than those self-hosted on a smaller target machine.
While this is not yet a universal procedure, it certainly provides a further opportunity to bring to bear tools to promote efficient programs.
In such a case, the requirement on the high order language is to give as much information to the compiler as possible without
overly restricting its options. This argument is contrary to the current practice of providing small subsets of a high
order language for min-computers. Such a subset would only restrict the amount of information
available to a compiler and would, of necessity, produce a less efficient code.
The computer would produce even poorer code if forced to host on a small-target machine.
No language is going to be of value unless it is used. There are many tangible and intangible influences
which will determine its final acceptability. The large scale acceptability of compilers is certainly the most
influential, tangible asset. Perhaps the only factor that this influences in language design should be the ability
to write compilers in the high order language.
That the language resembles something the customer is already familiar with is certainly going to be of considerable
importance. Arbitrary decisions on formats must be taken in the direction of existing DoD practice. The
possibility of making translators from existing programming languages to common languages will probably never appear
specifically as a requirement, since there is no intent at this time to perform such translations. However, it would be difficult to deny
the attractiveness of such a possibility if it existed.
IV. TABLE OF CONTENTS
III. GENERAL GOALS
IV. TABLE OF CONTENTS
V. THE NEEDED CHARACTERISTICS
V.A DATA AND TYPES
||[Assignment and Reference]
||[Truncation & Rounding]
||[Changes in Numeric Representation]
||[Power Set Operations]
V.C EXPRESSIONS AND PARAMETERS
||[Consistent Parameter Rules]
||[Type Agreement in Parameters]
||[Formal Parameter Kinds]
||[Formal Parameter Specifications]
||[Variable Number of Parameters]
V.D VARIABLES, LITERALS AND CONSTANTS
||[Constant Value Identifiers]
||[Initial Values of Variables]
||[Numeric Range and Step Size]
V.E DEFINITION FACILITIES
||[User Definitions Possible]
||[Consistent Use of Types]
||[No Default Declarations]
||[Can Extend Existing Operators]
||[Data Defining Mechanism]
||[No Free Union or Subset Types]
V.F SCOPES AND LIBRARIES
||[Separate Allocation & Access Allowed]
||[Limiting Access Scope]
||[Compile Time Scope Determination]
||[Libraries and Compools Indistinguishable]
||[Standard Library Definitions]
V.G CONTROL STRUCTURES
||[Kinds of Control Structures]
||[The GO TO]
||[Synchronization & Real Time]
V.H SYNTAX AND COMMENT CONVENTIONS
||[No Syntax Extensions]
||[Source Character Set]
||[Identifiers & Literals]
||[Lexical Units & Lines]
||[Uniform Referent Notation]
||[Consistency of Meaning]
V.I DEFAULTS, CONDITIONAL COMPILATION AND
||[No Defaults in Program Logic]
||[Object Representation Specification Optional]
||[Compile Time Variables]
||[Simple Base Language]
||[Object Machine Restrictions]
V.J EFFICIENT OBJECT REPRESENTATIONS AND
||[Efficient Object Code]
||[Optimizations Do Not Change Program Effect]
||[Machine Language Insertions]
||[Object Representation Specifications]
||[Open & Closed Routine Calls]
VI.A PROGRAM ENVIRONMENT
||[Operating System Not Required]
||[Software Development Tools]
||[Assertions & Other Optional Specifications]
||[No Superset Implementations]
||[No Subset Implementations]
||[Many Object Machines]
||[Self-Hosting Not Required]
||[Translator Checking Required]
||[Translator Internal Structure]
VI.C LANGUAGE DEFINITION, STANDARDS AND CONTROL
||[Existing Language Features Only]
||[Language Documentation Required]
||[Control Agent Required]
||[Support Agent Required]
||[Library Standards and Support Required]
V. THE NEEDED CHARACTERISTICS
The set of characteristics prescribed below represent a synthesis of the requirements submitted by the Military Departments
and are intended to be consistent with the language criteria of Section IV, to be
self-consistent, and to be achievable with existing computer software and hardware technology. The needed characteristics are the requirements
to be satisfied by an existing, modified or new language which is selected as a Common HOL. They prescribe capabilities and properties which
a common DoD language should possess but are not intended to impose any particular language features or mechanization of
those capabilities. The header of each item gives a general description of the needed language characteristic
[Ed: header titles have been added for clarity],
subsequent paragraph(s) of its body provide clarification, discuss some of the implications and
problems, provide the rationale behind its inclusion and/or further detail the requirement. The entire text,
and not just the headers, constitute the requirements.
The large number of characteristics reflects an attempt at thoroughness in dealing with the relevant issues.
Similarly, the length of the discussion for many items reflects the need to resolve the ambiguities, examine
and demonstrate the feasibility of the compendious statement introducing that characteristic. Because the
address issues in the design, implementation, and use of the language and properties of the resulting product,
be no correlation between the number of characteristics discussed here and the number of features in a language
which satisfies these characteristics. Many of the characteristics will influence the choice of many features, and every feature
will be influenced by many of the needed characteristics. Good language design is a unification process.
Any language which satisfies these characteristics must be smaller and simpler than the set of issues
underlying its choice.
V.A. DATA AND TYPES
V.A.1. [TYPED LANGUAGE]
The language will be typed. The type (or mode) of all variables,
components of composite data structures, expressions, operations, and parameters will be determinable at compile time and
unalterable at run time. The language will require that the type of each variable, and component of composite data structures
be explicitly specified in the source programs.
By the type of a data object is meant the set of objects themselves, the essential properties of those objects
and the set of operations which give access to, and take advantage of, those properties.
The author of any correct program in any programming language must, of
course, know the type of all data and variables used in his programs.
If the program is to be maintainable, modifiable and comprehensible by someone other than its author, the types of variables, operations,
and expressions should be easily determined from the source program.
Type specifications in programs provide the redundancy necessary to verify automatically that the programmer has adhered to his own type
conventions. Static type definitions also provide information at compile time
necessary for production of efficient object code. Compile time determination of types does not preclude the inclusion of language
structures for dynamic discrimination among alternative record formats (see A7) or among components of a
union type (E6). Where the subtype or
record structure cannot be determined until run time, it should still be fully discriminated in the program text so that all the
type checks can be completed at compile time.
V.A.2. [DATA TYPES]
The language will provide data types for integer, real (floating point and fixed point), Boolean and
character and will provide arrays (i.e., composite data structures with indexable components of homogeneous type) and records
(i.e., composite data structures with labeled components of heterogeneous type) as type generators.
These are the common data types and type generators of most programming language
and object machines. They are sufficient, when used with a data definition facility
(see E6, D6, and J1), to
efficiently mechanize other desired types.
The source language will require global (to a scope) specification of the precision for floating
point arithmetic and will permit precision specification for individual variables. This specification
will be interpreted as the maximum precision required by the program logic and the minimum precision to be
supported by the object code.
This is a specification of what the program needs, not what the hardware provides. Machine independence,
in the use of approximate value numbers (usually with floating point representation), can be achieved only if the user can place
constraints on the translator and object machine without forcing a specific mechanization of the arithhmetic precision specifications, as the maximum required by the object code, provide all the power and guarantees needed by the
programmer without unnecessarily constraining the object machine realization. Precision specifications apply to
arithmetic operations as well as to the data and therefore should be specified once for a designated scope. This permits
different precisions to be used in different parts of a program. Specification of the precision will
also contribute to the legibility and implementability of programs.
V.A.4. [FIXED POINT NUMBERS]
Fixed point numbers will be treated as exact quantities which have a range and a fractional step size which are
determined by the user at compile time. Scale factor management will be done by the compiler.
Scaled intgers are useful approximations to real numbers when dealing with exact quantity fractional values, when the
object machine does not have floating point hardware, and when greater precision is required than is available with
the floating point hardware. Integers will also be treated as exact quantities with
a step size equal to one.
V.A.5. [CHARACTER DATA]
Character sets will be treated as any other enumeration type.
Like any other data type defined by enumeration (see E6), it should
be possible to specify the program literal and order of characters.
These properties of the character set would be unalterable at run time.
The definition of a character set should reflect on the manner it is used within a program and not necessarily on the print
representation a particular physical device associates with a bit pattern at run time.
In general, unless all devices use the same character code, run-time translation
between character sets will be required. Widely used character sets, such as, USASCII and EBCDIC will be
available in a standard library. Note that access to a linear array filled with the
characters of an alphabet, A, and indexed by an alphabet, B, will convert
strings of characters from B to A.
The language will require user specification of the number of
dimensions, the range of subscript values for each dimension, and the
type of each array component. The number of dimensions, the type and
the lower subscript bound will be determinable at compile time. The upper subscript
bound will be determinable at entry to the array allocation scope.
This is general enough to permit both arrays which can be allocated at scope entry,
but does not permit dynamic change to the size of constructed arrays. It is sufficient to permit allocation of space
pools which the user can manage for allocation of more complex data
structures including dynamic arrays. The range of subscript values for
any given dimension will be a contiguous subsequence of values from an
enumeration type (including integers). The preferable lower bound on the
subscript range will be the initial element of an enumeration type or zero, because it
often contributes to program efficiency and clarity.
The language will permit records to have alternative structures, each of which is fixed at compile time.
The name and type of each record component will be specified by the user at compile time.
This provides all that is safe to use in CMS-2 and JOVIAL OVERLAY and in FORTRAN EQUIVALENCE.
It permits hierarchically structured data of heterogeneous type, permits records to have alternative structures
as long as each structure is fixed at compile time and the choice is fully discriminated at run time, but it does not permit arbitrary
references to memory nor the dropping of type checking when handling overlaid structures. The discrimination condition will
not be restricted to a field of the record but should be of any Boolean expression.
V.B.1. [ASSIGNMENT AND REFERENCE]
Assignment and reference operations will be automatically defined for all data types which do not manage
their data storage. The assignment operation will permit any value of a given type to be assigned to a variable,
array or record component of that type or of a union type containing that type. Reference will retrieve the last assigned value.
The user will be able to declare variables for all data types.
Variables are useful only when there are corresponding access and assignment operations.
The user will be permitted to define assignment and access operations as part of encapsulated
type definitions (see E5). Otherwise, they will be automatically defined
for types which do not manage the storage for their data. (See D5 for
The source language will have a built-in operation which can be used to compare any two data objects (regardless of type) for identity.
Equivalence is an essential universal operation which should not be subject to restriction on its use.
There are many useful equivalence operations for some types and a language definition cannot forsee all these
for user defined types. Equivalence meaning logical identity and not bit-by-bit comparison on the internal data representation,
however, is required for all data types. Proper semantic interpretation of identity requires that equality and identity be the
same for atomic data (i.e., numbers, characters, Boolean values, and types defined by enumeration) and that elements of disjoint
types never be identical. Consequently, its usefulness at run time is restricted to data of the same type or to types with
nonempty intersections. For floating point numbers identity will be defined as the same within the specified
Relational operations will be automatically defined for numeric data and all types defined by enumeration.
Numbers and types defined by enumeration have an obvious ordering which should be available through relational operations. All six
relational operations will be included. It will be possible to inhibit ordering definitions
when unordered sets are intended.
V.B.4. [ARITHMETIC OPERATIONS]
The built-in arithmetic operations will include: addition, subtraction, multiplication, division (with a real result), exponentiation,
integer division (with integer or fixed point arguments and remainder), and negation.
These are the most widely used numeric operations and are available as hardware operations in most machines.
Floating point operations will be precise to at least the specified precision.
V.B.5. [TRUNCATION AND ROUNDING]
Arithmetic and assignment operations on data which are within the range specifications of the program will never
truncate the most significant digits of a numeric quantity. Truncation and rounding will always be on the least
significant digits and will never be implicit for integers and fixed point numbers. Implicit rounding beyond the specified precision
will be allowed for floating point numbers.
These requirements seem obvious, particularly for floating point numbers, and yet many of our existing languages truncate the most significant mantissa
digits in some mixed and floating point operations.
V.B.6. [BOOLEAN OPERATIONS]
The built-in Boolean operations will include "and," "or," "not," and "nor."
The operations "and" and "or" on scalars will be evaluated in short circuit mode.
Short circuit mode, as used here, is a semantic rather than an implementation distinction and means that "and" and "or" are
in fact control operations which do not evaluate side effects of their second argument if the value of the first argument is "false"
or "true," respectively. Short circuit evaluation has no disadvantages over the corresponding computational operations, sometimes
produces faster executing code in languages where the user can rely on the short circuit execution, and improves the clarity and
maintainability of programs by permitting expressions such as, "1 <= 7 & A(i) > x", which could be
erroneous were short circuit execution not intended. Note that the equivalence and
nonequivalence operations (see B2) are the same as logical
equivalence and exclusive-or respectively.
V.B.7. [SCALAR OPERATIONS]
The source language will permit scalar operations and assignment on conformable arrays, and will permit data transfers
between records or arrays of identical logical structure.
Conformability will require exactly the same number of components (although a scalar can be considered compatible with any array),
and one for one compatibility in type. Correspondence will be by position in similarly shaped arrays. In many situations component by component
operations are done on array elements. In fact, a primary reason for having arrays is to permit large numbers of similarly
treated objects to have a uniform notation. Component by component operations available directly in the
source language hide the details of the sequencing and thereby, simplify the program and make more optimizations available.
In addition, they permit simultaneous execution on machines with parallel processing hardware.
Although component by component operations will be available for built-in composite data structures which are used
to define application-oriented structures, that capability will not be automatically
inherited by defined data structures.
A matrix might be defined using an array, but it will not inherit the array operations automatically.
Multiplication for matrices would, for example, be unnatural, confusing and inconvenient if the product operator
for matrices were interpreted as a component by component operation instead of
cross product of corresponding row and column vectors. Component by component operations also allow operations
on character strings represented as vectors of characters, and allow efficient Boolean vector operations.
V.B.8. [TYPE CONVERSIONS]
There will be no implicit type conversions, but no conversion operation will be required when the type of an
actual parameter is a constituent of a union type which is the formal parameter. The language will
provide explicit conversion operations among integer, fixed point and floating point data,
between the object representation of numbers and their representations as characters, and between fixed point scale factors.
Implicit type conversions which represent changes in the value of data items without an explicit indicator in the program,
are not only error prone but can result in unexpected run time overhead.
V.B.9. [CHANGES IN NUMERIC REPRESENTATION]
Explicit conversion operations will not be required between numerical ranges. There will be a run time exception condition when
any integer or fixed point value is truncated.
Because ranges do not form closed systems, range validation is not possible at compile time (e.g., "I := I+1" may be a range error).
At best, the compiler might pont out likely range errors. (This requirement is optional for hardware installations which do not
have overflow detection).
V.B.10. [I/O OPERATIONS]
The base language will provide operations allowing programs to interact with files, channels or devices including terminals. These
operations will permit sending and receiving both data and control information, will enable programs to dynamically assign and
reassign I/O devices, will provide user control for exception conditions, and will not be installation dependent.
Whether the referenced "files" are real or virtual and whether they
are hardware devices, I/O channels or logical files depends on the object machie
configuration and on the details of its operating system if present. But in
any programming system, I/O operations ultimately reduce to sending or
receiving data and/or control information to a file or to a device controller. These can be made accessible
in a HOL in an abstract form through a small set of generic I/O operations (like "read" and "write," with
appropriate device and exception parameters). Note that devices and files are similar in many aspects to types, so additional
language features may not be required to satisfy this requirement. This requirement, in conjunction with
requirement E1, permits user definition of unique equipments and their associated I/O
operations as data types within the syntactic and semantic framework provided by the generic operations.
V.B.11. [POWER SET OPERATIONS]
The language will provide operations on data types defined as power sets of enumerations types (see E6).
These operations will include union, intersection, difference, complement, and an element predicate.
As with any data type, power sets will be useful only if there are operations which can create, select and
interrogate them. Note that this provides only a very special class of sets but one which is very
useful for computations on sets of indicators, flags, and similar devices in monitoring and control applications.
More general sets, if desired, must be defined using the type definition facilities.
V.C. EXPRESSIONS AND PARAMETERS
V.C.1. [SIDE EFFECTS]
Side effects which are dependent on the evaluation order among the arguments of an expression will be
This is a semantic restriction on the evaluation order of arguments to expressions. It provides an explicit rule
(i.e., left-to-right) for order of argument evaluation, but allows the implementations to alter the actual order in any way
which does not change the effect. This provides the user with a simple rule for determining the effects of interactions among
argument evaluations without imposing a strict rule on compilers which are sophisticated enough to detect potential side-effects and
optimize through reordering of arguments whne the evaluation order does not affect the result. Control operations (e.g.,
conditional and iterative control structures), of course, must be
exceptions to this general rule since control operations are in fact those operations
which specify the sequencing and evaluation rules for
V.C.2. [OPERAND STRUCTURE]
Which parts of an expression constitute the operands to each operation within that expression
should be obvious to the reader. There will be few levels of operator hierarchy and they will be widely recognized.
Care must be taken to ensure that the operator/operand structure of expressions is not
psychologically ambiguous (i.e., to guarantee that
the parse implemented by the language is the same as intended by the
programmer, and understood by those reading the program. This kind of problem can
be minimized by having few precedence levels and parsing rules,
by allowing explicit parentheses to specify the intended
and by requiring explicit parentheses when the execution order
is of significance to the result within the same precedence level (e.g., "A divided by Y divided by Z" and X divided by
Y x Z"). The user will not be able to define new operator precedence rules nor change the precedence of existing operators.
V.C.3. [EXPRESSIONS PERMITTED]
Expressions of a given type will be permitted anywhere in source programs where both constants and
references to variables of that type are allowed.
This is an example of not imposing arbitrary restrictions and special case rules on the user of the
source language. Special mention is made here only because so many languages do restrict the form of expressions. FORTRAN, for example, has a list of
seven different syntactic forms for subscript expressions, instead of allowing all
forms of arithmetic expressions.
V.C.4. [CONSTANT EXPRESSIONS]
Constant expressions will be allowed in programs anywhere constants are allowed, and constant expressions will be
evaluated before run time.
The ability to write constant expressions in programs has proven valuable in languages with this capability,
particularly with regard to program readability and in avoiding programmer error in externally evaluating
and transcribing constant expressions. They are most often used in declarations.
There is no need, however, that constant expressions impose run time costs for their evaulation. They can be evaluated
once at compile time or, if this is inconvenient because of incompatibilities between the host and object
machines, the compiler can generate code for their evaluation at load time. In any case, the resulting value should
be the same (at least within the stated precision) regardless of the object machine (see D2).
Allowing constant expressions in place of constants can improve the clarity, correctness, and maintainability of
programs and does not impose any run time costs.
V.C.5. [CONSISTENT PARAMETER RULES]
There will be a consistent set of rules applicable to all parameters, whether they be for procedures, for types, for exception handling, for parallel processes, for declarations,
or for built-in operators. There will be no special operations (e.g., array substructuring) applicable only to parameters.
Uniformity and consistency contributes to ease of learning,
implementing and using a language; allows the user to concentrate on the programming task
instead of the language; and leads to more readable, understandable, and predictable programs.
V.C.6. [TYPE AGREEMENT IN PARAMETERS]
Formal and actual parameters will always agree in type. The number of dimensions for array parameters will be determinable at
compile time. The size and subscript range for array parameters need not be determinable at compile time,
but can be passed as part of the parameter.
Type transfers hidden in procedure calls with incompatible formal and actual parameters,
whether intentional or accidental, have long been a source of program errors and of programs which are difficult to maintain.
On the other hand, there is no reason why the subscript ranges for arrays cannot be passed as part of the arguments.
Some notations permit such parameters to be implicit on the call side. Formal parameters of a union type
will be considered conformable to actual parameters or any of the component types.
V.C.7. [FORMAL PARAMETER KINDS]
There will be only four classes of formal parameters. For data there will be those which act as
constants representing the actual parameter value
at the time of call, and those which rename the actual parameter which must be a variable.
In addition, there will be a formal
parameter class for specifying the control action when exception conditions occur, and a
class for procedure parameters.
The first class of data parameter acts as a constant within the procedure body and cannot be assigned to
nor changed during the procedure execution; its corresponding actual parameter may be any legal expression
of the desired type and will be evaluated once at the time of call. The second class of data parameter renames
the actual parameter which must be a variable, the address of the actual parameter variable will be determined by (or at) the time of call
and unalterable during execution of the procedure, and assignment (or reference) to the formal parameter name
will assign (or access) the variable which is the actual parameter. They are the only two
widely used parameter binding mechanisms for data and the many alternatives (at least 10 have been
suggested) add complexity and cost to a language without sufficiently
increasing the clarity or power.
A language with exception handling capability must have a way to pass control and related data through procedure call interfaces.
Exception handling control parameters will be specified on the call side only when needed. Actual parameters
will be restricted to those of similar (explicit or implicit) specification parts.
V.C.8. [FORMAL PARAMETER SPECIFICATIONS]
Specification of the type, range, precision, dimension, scale and format of parameters will be optional on the
formal side. None of them will be alterable at run time.
Optional formal parameter specification permits the writing of generic procedures which are instantiated at compile
time by the characteristics of their actual parameters. It eliminates the need for compile time "type" parameters. This generic
procedure capability, for example, allows the definition of stacks and queues and their associated operations on data of any given type
without knowing the data type when the operations are defined.
V.C.9. [VARIABLE NUMBER OF PARAMETERS]
There will be provision for variable numbers of arguments, but in such cases all but a constant number of them must be of the same type.
Whether a routine can have a variable number of arguments must be determinable from its description,
and the number of arguments for any call will be determinable at compile time.
There are many useful purposes for procedures with variable numbers of arguments. These include intrinsic functions such as "print,"
generalizations of operations which are both commutative and associative such as "max " and "min," and
repetitive application of the same binary operation such as the Lisp "list" operation. The use of variable number
of argument operations need not, and will not, cause relaxation of any compile time checks, require use of multiple entry
procedures, allow the number of actual parameters to vary at run time, nor require special calling mechanisms.
If the parameters which can vary are limited to a program specified type treated as any other argument on the call side
and as elements of an array within the procedure definition, full type
checking can be done at compile time. There will be no prohibition on writing a special case of a procedure for a particular number of arguments.
V.D. VARIABLES, LITERALS AND CONSTANTS
V.D.1. [CONSTANT VALUE IDENTIFIERS]
The user will have the ability to associate constant values of any type with identifiers.
The use of identifiers to represent literal values has often made programs more readable, more easily
modifiable and less prone to error when the value of a constant is changed. Associating constant values
with an identifier is preferable to assigning the value to a variable because it is then clearly marked in the
program as a constant, can be automatically checked for unintentional changes, and often can have a more efficient
V.D.2. [NUMERIC LITERALS]
The language will provide a syntax and a consistent interpretation for literals of built-in data types.
Numeric literals will have the same value (within the specified precision) in both programs and data (input or output).
Literals are needed for all atomic data types and should be provided as part of the language definition for built-in types.
Regardless of the source of the data and regardless of the object machine, the value of constants should be the same. For
integers it should be exact and for reals it should be the same within the specified precision. Compiler writers, however,
would disagree. They object to this requirement on two grounds: that it is too costly if the host and object machines are different, and that it is
unnecessary if they are the same. In fact, all costs are at compile time and must be insignificant compared to the life time costs
resulting from object code containing the wrong constant values. As for being unnecessary, there have been all too many
cases of different values from program and data literals on the same machine because
the compile time and run time conversion packages were different and imprecise.
V.D.3. [INITIAL VALUES OF VARIABLES]
The language will permit the user to specify the initial values of individual variables as part of their declaration.
Such variables will be initialized at the time of their apparent application (i.e., at entry to allocation scope).
There will be no default initial values.
The ability to initialize variables at the time of their allocation will contribute to program clarity, but a requirement to do so would be
an arbitrary and sometimes costly decision to the user. Default initial values, on the other hand, contribute to
neither program clarity nor correctness and can be even more costly at run time. It is usually a programming
error if a variable is accessed before it is initialized. It is desirable that the translator give a warning when a
path between the declaration and use of a variable omits initialization. Whether a variable will be assigned is, in general,
an unsolvable problem, but it is sometimes determinable whether assignments occur on potential paths. In the case of
arrays, it is possible at compile time only to determine that
some components (but not necessarily which) have been initialized. There will be
provision (at user option) for run time testing for initialization.
V.D.4. [NUMERIC RANGE AND STEP SIZE]
The source language will require its users to specify individually the range of all numeric variables
and the step size for fixed point variables. The range specifications will be interpreted as the maximal range of values which
will be assigned to a variable and the minimal range which must be supported by the object code. Range and step
size specifications will not be interpreted as defining new types.
Range specifications are a special form of assertion. They aid in understanding and determining the correctness of
programs. They can also be used as additional information by the compiler in deciding what storage and allocation to use
(e.g., half words might be more efficient for integers in the range 0 to 1000). Range specifications also offer
the opportunity for the translator to insert range tests automatically for run time or debug time validation of the program
logic. With the ranges of variables specified in the program, it becomes possible to
perform many subscript bounds checks at compile time. These bounds checks, however, can be only as valid
as the range specifications which cannot, in general, be validated at compile time.
Range specifications on approximate
valued variables (usually with floating point implementation) also offer the possibility of
their implementation using
fixed point hardware.
V.D.5. [VARIABLE TYPES]
The range of values which can be associated with a variable, array, or record component will be any built-in type,
any defined type or a contiguous subsequence of any enumeration type.
There should not be any arbitrary restrictions on the structure of data.
This permits arrays to be components of records or arrays,
and permits records to be components of arrays.
V.D.6. [POINTER VARIABLES]
The language will provide a pointer mechanism which can be used
to build data with shared and/or recursive substructure. The pointer property will only affect the size of variables (including
arrays and record components) of some data types. Pointer variables will be as safe in their use as are any other variables.
Assignment to a pointer variable will mean that the variable's name is to act as an additional label (or reference)
on the datum being assigned. Assignment to a nonpointer variable will mean that the variable's name is to label
a copy of the object being assigned. For data without alterable component structure or alterable component values,
there is no functional difference between reference to multiple copies and
multiple references to a single copy. Consequently, pointer/nonpointer will be a property only of variables for
composite types, and of composite array and record components. Because the pointer/nonpointer property applies to
all variables of a given type, it will be specified as part of the type definition. The use of pointers
will be kept safe by prohibiting pointers to data structures whose allocation scope is narrower than that of the pointer variable.
Such a restriction is easily enforced at compile time using hierarchical scope rules, providing there is no way to dynamically
create new instances of the data type. In the latter case, the dynamically created data can be allocated with full safety using a (user or library
defined) space pool which is either local (i.e., own) or global to the type
definition. If variables of a type do not have
the pointer property, then dynamic storage allocation would be required for assignment unless
their size is constant and known at the time of variable allocation.
Thus, the nonpointer property will be permitted only for types
- whose data have a structure and size which is constant in the type definition, or
- which manage the storage for their data as part of the type definition.
Because pointers are often less expensive at run time than nonpointers, and are subject to fewer restrictions,
the specification of the nonpointer property will be explicit in programs (this is similar to the
Algol-60 issue concerning the explicit specification of "value" (i.e., nonpointer) and "name" (i.e., pointer).
The need for pointers is obvious in building data structures with shared or
recursive substructures; such as, directed graphs, stacks, queues, and list structures. Providing pointers as absolute address types,
however, produces gaps in the type checking and scope mechanism. Type and access restricted pointers will provide the power
of general pointers without their undesirable characteristics.
V.E. DEFINITION FACILITIES
V.E.1. [USER DEFINITIONS POSSIBLE]
The user of the language will be able to define new data types and operations within his programs.
The number of specialized capabilities needed for a common language is large and diverse. In many cases, there is no concensus
as to the form these capabilities should take in a programming language. The operational requirements
dictating specific specialized language capabilities are volatile, and future needs cannot always be foreseen. No language
can make available all the features useful to the broad spectrum of military applications, anticipate
future applications and requirements, or even provide a universally "best" capability in support of a single
application area. A common language needs capability for growth. It should contain all the power necessary
to satisfy all the applications, and the ability to specialize that power to the particular application task.
A language with defining facilities for data and operations often makes it possible to add new
application-oriented structures, and to use new programming techniques and mechanisms through descriptions
written entirely within the language. Definitions will have the appearance and costs of
features which are built into the language, while actually being
catalogued, accessible application packages. The operation definition facility will include the ability to define new infix
operators (but see H2 for restrictions). No programming language can be all things to all
people, but a language with data and operation definition facilities can be adapted to meet changing requirements in a variety of areas.
The ability to define data and operations is well within the state of the art. Operation definition
facilities in the form of subroutines have been available in all general purpose programming languages since
at least the time of early FORTRANs. Data definition facilities have been available in a variety of programming
languages for almost 10 years, and reached their peak with a large number of extensible languages (Stephen A. Schuman (Ed.)
Proceedings of the International Symposium on Estensible Languages, SIGPLAN Notices, Vol. 6, No. 12,
December 1971. Also C. Christensen and C.J. Shaw (Ed.), Proceedings of the Extensible
Language Symposium, SIGPLAN Notices 4, August 1969.) (over 30) in 1968 and shortly thereafter. A trend toward more
abstract and less machine-oriented data specification mechanisms has appeared more recently in
PASCAL (Niklaus Wirth, "An Assessment of the Programming Language PASCAL, "Proceedings of the International Conference
on Reliable Software 21-23 April 1973, P. 23-30). Data type definitions,
with operations and data
defined together, are used in several languages including SIMULA-67 (Jacob Palme, "SIMULA as a Tool for Extensible
Program Products, "SIGPLAN Notices, Vol. 9, No. 4, February 1974). On
the other hand, there is currently much ferment as to what is the proper
function and form of data type definitions.
V.E.2. [CONSISTENT USE OF TYPES]
The "use" of defined types will be indistinguishable from built-in types.
Whether a type is built-in or defined within the base will not be
determinable from its syntactic and semantic properties. There will be no ad hoc special cases
nor inconsistent rules to interfere
with and complicate learning, using and implementing the language. If built-in features and user defined data structures
and operations are treated in the same way throughout the language, so that the
base language, standard application libraries and application programs are treated in a uniform manner by the user and by the
translator, then these distinctions will grow dim to everyone's advantage.
When the language contains all the essential power, when few can tell the difference between the base language
and library definitions, and when the introduction of new data types and routines does not impact the
compiler and the language standards, then there is little incentive to proliferate languages.
Similarly, if type definitions are processed entirely at compiler time, and the language allows full program
specification of the internal representation, there need be no penalty in run time efficiency for using defined types.
V.E.3. [NO DEFAULT DECLARATIONS]
Each program component will be defined in the base language, in
a library, or in the program. There will be no default declarations.
As programmers, we should not expect the translator to write our programs for us
(at least in the immediate future). If we somehow know that the translator's default convention is compatible with our needs
for the case at hand, we should still document the choice so others can
understand and maintain our programs. Neither should we be able to
delay definitions (possibly forget them) until they cause trouble in
the operational system. This is a special case of requirement I1.
V.E.4. [CAN EXTEND EXISTING OPERATORS]
The user will be able, within the source language, to extend existing operators to new data types.
When an operation is an abstraction of an existing operation for a new type,
or is a generalization of an existing
operation, it is inconvenient, confusing and misleading to use any but the existing operator symbol or function
named. The translator will not assume that commutativity of built-in operations is preserved by extensions, and
any assumptions about the associativity of built-in or extended operations will be ignored by the
translator when explicit parentheses are provided in an expression.
V.E.5. [TYPE DEFINITIONS]
Type definitions in the source language will permit definition of both the class of data objects comprising the type,
and the set of operations applicable to that class. A defined type wil not automatically inherit the operations of the data
with which it is represented.
Types define abstract data objects with special properties. The data objects are given a representation in terms of existing data
structures, but they are of little value until operations are available to take advantage of their
special properties. When one obtains access to a type, he needs its operations as well as its data.
Numeric data is needed in many applications but is of little value to any without arithmetic operations. The
definable operations will include constructors,
selectors, predicates, and type conversions.
V.E.6. [DATA DEFINING MECHANISMS]
The data objects comprising a defined type will be definable by enumeration of their literals names,
as Cartesian products of existing types (i.e., as array and record classes), by discriminated union
(i.e., as the union of disjoint types) and as the power set of an enumeration type. These definitions
will be processed entirely at compile time.
The above list comprises a currently known set of useful definitional mechanisms for data types
which do not require run time support, as do garbage collection and dynamic storage allocation.
In conjunction with pointers (see D6), they provide
many of the mechanisms necessary to define recursive data structures and
efficient sparse data structures.
V.E.7. [NO FREE UNION OR SUBSET TYPES]
Type definitions by free union (i.e., union of non-disjoint types) and subsetting are not desired.
Free union adds no new power not provided by discriminated union, but does
require giving up the security of types in return for programmer freedom.
Range and subset specifications on variables are useful documentation and
debugging aids, but will not be construed as types. Subsets do not introduce new properties or operations not
available to the superset and often do not form a closed system under the superset operations. Unlike types,
membership in subsets can be determined only at run time.
V.E.8. [TYPE INITIALIZATION]
When defining a type, the user will be able to specify the intialization and finalization procedures for the type and the actions to be
taken at the time of allocation and deallocation of variables of that type.
It is often necessary to do bookkeeping or to take other special action when variables of a given type are
allocated or deallocated. The language will not limit the class of definable types by withholding the ability
to define those actions. Initialization might take place once when the type is allocated (i.e., in its allocation scope)
and would be used to set up the procedures and initialize the variables which are
local to the type definition. These operations will be definable in the encapsulation housing the rest of the type definition.
V.F. SCOPES AND LIBRARIES
V.F.1. [SEPARATE ALLOCATION AND ACCESS ALLOWED]
The language will allow the user to distinguish between scope of allocation and scope of access.
The scope of allocation or lifetime of a program structure is that region of the program for which the object representation of the structure would be present. The allocation scope defines the program scope
for which own variables of the structure must be maintained and identifies the time for initialization of
the structure. The access scope defines the regions of the program in which the allocated structure is
accessible to the program and will never be wider than the
allocation scope. In some cases the user may desire that each use of a
defined program structure be independent (i.e., the allocation and accessing scopes would be identical).
In other cases, the various accessing scopes might share a common allocation of the structure.
V.F.2. [LIMITING ACCESS SCOPE]
The ability to limit the access to separately defined structures will be available both where the structure
is defined and where it is used. It will be possible to associate new local names with separately
defined program components.
V.F.3. [COMPILE TIME SCOPE DETERMINATION]
The scope of identifiers will be wholly determined at compile time.
V.F.4. [LIBRARIES AVAILABLE]
A variety of application-oriented data and operations will be available in libraries and easily accessible in the language.
A simple base alone is not sufficient for a common language. Even though in theory such a language
provides the necessary power and the capability for specialization to particular applications,
the users of the language cannot be expected to develop and support common libraries under
individual projects. There will be broad support for libraries common to users of well recognized
application areas. Application libraries will be developed as early as possible.
V.F.5. [LIBRARY CONTENTS]
Program components not defined within the current program, and not
in the base language, will be maintained in compile time accessible libraries. The libraries will be capable of holding anything
definable in the language, and will not exclude routines whose bodies are written in other source languages.
The usefulness of a language derives primarily from the existence and accessibility of specialized application-oriented data and
operations. Whether a library should contain source or object code is a question of
implementation efficiency and should not be specified in the definition of the source language, but the source
language description will always be available. It should be remembered, however, that interfaces
cannot be validated at program assembly time without some equivalent of their source language interface specifications,
that object modules are machine-dependent and, therefore, not portable, that source code is often more
compact than object code, and that compilers for simple
languages can sometimes compile faster than a loader can load from relocatable object programs.
Library routines written on other languages will not be prohibited provided the foreign routine has object
code compatible with the calling mechanisms used in the Common HOL,
and providing sufficient header information (e.g., parameter types, form and
number) is given with the routine in Common HOL form to permit the required
compile time checks at the interface.
V.F.6. [LIBRARIES AND COMPOOLS INDISTINGUISHABLE]
Libraries and Compools will be indistinguishable. They will be
capable of holding anything definable in the language, and it will be possible to associate them with any level of programming activity
from systems through projects to individual programs. There will be many
specialized compools or libraries, any user-specified subset of which is immediately accessible
from a given program.
Compools have proven very useful in organizing and controlling shared data structures and shared routines. A
similar mechanism will be available to manage and control access to related library definitions.
V.F.7. [STANDARD LIBRARY DEFINITIONS]
The source language will contain standard machine independent interfaces to machine dependent
capabilities, including peripheral equipment and special hardware.
The convenience, ease of use and savings in production and maintenance costs resulting from using high order languages come from
being able to use specialized capabilities without building them from scratch. Thus, it is essential that high level capabilities
be supplied with the language. The idea is not to provide all the many cases in the language, but to provide a few general cases
which will cover the special cases.
There is currently little agreement on standard operating system, I/O, or file system interfaces. This does not
preclude support of one or more forms for the near term. For the present the important thing is that
one be chosen and made available as a standard supported library definition which
the user can use with confidence.
V.G. CONTROL STRUCTURES
V.G.1. [KINDS OF CONTROL STRUCTURES]
The language will provide structured control mechanisms for sequential, conditional, iterative, and recursive
control. It will also provide control structures for (pseudo) parallel processing,
exception handling and asynchronous interrupt handling.
These mechanisms, hopefully, provide a spanning set of control structures. The most appropriate
operations in several of these areas is an open question. For the present, the choice will be a spanning set of composable control
structures, each of which is easily mapped onto object machines and which does not impose run time charges when it is not used.
Whether parallel processing is real (i.e., by multiprocessing) or is synthesized on a single sequential
processor, is determined by the object machine, but if programs are written as if there
is true parallel processing (and no assumption about the relative speed
of the processors), then the same results will be obtained independent of the object environment.
It is desirable that the number of primitive control structures in the language be minimized, not by reducing the power of the
language, but by selecting a small set of composable primitives which can be used to easily build other desired control mechanisms
within programs. This means that the capabilities of control mechanisms must be separable so that the user need not pay either program
clarity or implementation costs for undesired specialized capabilities. By those criteria, the Algol-60 "for" would be undesirable because
it imposes the use of a loop control variable, requires that there be a single terminal condition and
that the condition be before each iteration. Consequently, "for" cannot be composed to build other useful,
iterative control structures (e.g., FORTRAN "DO"). The ability to compose control structures does not imply
an ability to define new control operations, and such an ability is in conflict with
the limited parameter passing mechanisms of C7.
V.G.2. [THE GO TO]
The source language will provide a "go to" operation applicable to program labels within its most local scope of definition.
The "go to" is a machine level capability which is still needed to fill in any gaps which might remain in the choice
of structured control primitives, to provide compatibility for transliterating programs written
in older languages, and because of the wide familiarity of current practitioners with its use. The language
should not, however, impose unnecessary costs for its presence. The "go to" will be limited to explicitly specified
program labels at the same scope level. Neither should the language provide specialized facilities which encourage
its use in dangerous and confusing ways. Switches, designational expressions, label variables, label parameters
and numeric labels are not desired. Switches here refer to the unrestricted
switches which are generalizations of the "go to", and not to case statements which are a general form for conditionals
(see G3). This requirement should not be interpreted to conflict with the
specialized form of control transfer provided by the exception handling control structures of G7
V.G.3. [CONDITIONAL CONTROL]
The conditional control structures will be fully partitioned and will permit selection among alternative computations based on the
value of a boolean expression, on the subtype of a value from a
discriminated union, or on a computed choice among labeled alternatives.
The conditional control operations will be fully partitioned (e.g., an "else" clause must follow each "if then") so the choice
is clear and explicit in each case. There will be some general form of conditional which allows an
arbitrary computation to determine the selected situation (e.g., Zahn's device (Donald E. Knuth, "Structured programming with Go To Statements," ACM
Computer Surveys, Vol. 6, No. 4, December 1974) provides a good solution to the general problem). Special
mechanisms are also needed for the more common cases of the Boolean expression (e.g., "if then else")
and for value or type discrimination (e.g., "case" on one of a set of values or subtype of a union).
V.G.4. [ITERATIVE CONTROL]
The iterative control structure will permit the termination condition to appear anywhere in the loop,
will require control variables to be local to the iterative control, will allow entry only at the head of the loop,
and will not impose excessive overhead in clarity, or run time execution for common special case termination conditions
(e.g., FORTRAN "DO" or Algol-60 "for").
In its most general form, a programmed loop is executed repetitively until some computed predicate becomes true.
There may be more than one terminating predicate, and they might appear anywhere in the loop. Specialized control
structures (e.g., "while do") have been used for the common situation in which the termination conditions precedes each
iteration. The most common case is termination after a fixed number of iterations and a specialized control
structure should be provided for that purpose (e.g., FORTRAN "DO" or Algol-60 "for").
A problem which arises in many programming languages is that loop control variables are global to the iterative control
and, thus, will have a value after loop termination, but that value is usually an accident of the implementation.
Specifying the meaning of control variables after loop termination in the language definition resolves the ambiguity but must be an arbitrary
decision which will not aid program clarity or correctness, and may interfere with the generation of
efficient object code. Loop control variables are, by definition, variables used to control the repetitive
execution of a programmed loop and, as such, will be local to the loop body, but at loop termination it will be possible
to pass their value (or any other computed value) out of the loop, conveniently and efficiently.
Recursive as well as nonrecursive routines will be available in the source language. It will not be possible
to define procedures within the body of a recursive procedure.
Recursion is desirable in many applications because it contributes directly to their elegance and clarity, and
simplifies proof procedures. Indirectly, it contributes to the reliability and maintainability of some programs.
Recursion is required in order to avoid unnecessarily opaque, complex and confusing programs when operating on recursive
data structures. Recursion has not been widely used in DoD software because
many programming languages do not provide recursion, practitioners are not familiar with its use, and users fear
that its run time costs are too high. Of these, only the run time costs would justify its exclusion
from the language.
A major run time cost often attributed to recursion is the need for the presence of a set of "display" registers which
are used to keep track of the addresses of the various levels of lexically embedded environments and which
are global to their own definition, but local to a more global recursive procedure.
This possibility can easily be removed by prohibiting the definition of procedures
within the body of a recursive procedure.
The utility of such a combination of capabilities is very questionable, and this single restriction will eliminate
all added execution costs for nonrecursive procedures in programs which contain recursive procedures.
As with any other facility of the language, routines should be implemented in the most efficient manner
consistent with their use, and the language should be designed so that efficient implementations are possible.
In particular, the most possible regardless of
whether the language, or even the program, contains recursive procedures. When any routine makes a procedure
call as its last operation before exit (and this is quite common for recursive routines), the implementation
might use the same data area for both routines, and do a jump to the head of the called procedure, thereby saving
much of the overhead of a procedure call and eliminating a return.
The choice between recursive and nonrecursive routines involves trade-offs. Recursive routines can aid program clarity
when operating on recursive data, but can detract from clarity when operating on iterative data.
They can increase execution time when procedure call overhead is greater than
loop overhead, and can decrease execution times when loop overhead is the more expensive. Finally, program storage for
recursive routines is often only a small fraction of that for a
corresponding iterative procedure, but the data storage requirements are
often much larger because of the simultaneous presence of several activations of the same procedure.
V.G.6. [PARALLEL PROCESSING]
The source language will provide a parallel processing capability. This capability should include the ability to create and
terminate (possibly pseudo) parallel processes, and for these
processes to gain exclusive use of resources during specified portions of their execution.
A parallel processing capability is essential in embedded computer applications. Programs must send data to,
receive data from, and control many devices which are operating in parallel.
Multiprogramming (a form of pseudo parallel processing) is necessary so that many programs within a system
can meet their differing real time constraints. The parallel processing
capability will minimally provide the ability to define and call parallel processing and the ability to gain exclusive use
of system resources in the form of data structures, devices and pseudo devices. This latter ability satisfies one of the two needs
for synchronization of parallel processes. The other is required in conjunction with real time constraints
The parallel processing capability will be defined as true parallel (as opposed to coroutine) primitives,
but with the understanding that in most implementations the object computer will have fewer processors
(usually one) than the number of parallel paths specified in a program. Interleaved execution in the
implementation may be required.
If the language permits several simultaneous activations of a given parallel process, then it might
require the user to give an upper bound on the number which can exist simultaneously. The latter requirement
is reasonable for parallel processes because it is information known by the programmer, and necessary
to the maintainer, because parallel processes cannot normally be stacked, and because it is
necessary for the compilation of efficient programs.
V.G.7. [EXCEPTION HANDLING]
The exception handling control structure will permit the user to cause transfer of
control and data for any error or exception situation which might occur in a program.
It is essential in many applications that there be no program halts beyond the user's control.
The user must be able to specify the action to be taken on any exception situation which might occur within his program.
The exception handling mechanism will be parameterized so data can be passed to the recovery point. Exception situations
might include arithmetic overflow, exhaustion of available space, hardware errors, any user-defined exceptions and any
run time detected programming error.
The user will be able to write programs which can get out of an arbitrary nest of control and intercept it
at any embedding level desired. The exception handling mechanism will permit the user to specify the
action to be taken upon the occurrence of a designation exception within any given access scope of the program. The transfers
of control will, at the user's option, be either forward in the program (but never to a narrower
scope of access or out of a procedure) or out of the current procedure through its dynamic (i.e., calling structure).
The latter form requires an exception handling formal parameter class (see C7).
V.G.8. [SYNCHRONIZATION AND REAL TIME]
There will be source language features which permit delay on any control path until some
specified time or situation has occurred, which permit specification of the relative priorities among
parallel control paths, which give access to real time clocks, which
permit asynchronous hardware interrupts to be treated as any other exception situation.
When parallel or pseudo parallel paths appear in a program it must be possible to specify
their relative priorities and to synchronize their executions. Synchronization can be done either through
exclusive access to data (see G6) or through delays terminated by designated
situations occurring within the program. These situations should
include the elapse of program specified time intervals,
occurrence of hardware interrupts and those designated in the program.
There will be no implicit evaluation of program determined situations.
Time delays will be program specifiable for both real and simulated times.
V.H. SYNTAX AND COMMENT CONVENTIONS
V.H.1. [GENERAL CHARACTERISTICS]
The source language will be free format with an explicit statement separator, will allow the use of
mnemonically significant identifiers, will be based on conventional forms, will have a simple, uniform
and easily parsed grammar, will not provide unique notations for special cases, will not permit
abbreviation of identifiers or key words, and will be syntactically unambiguous.
Clarity and readability of programs will be the primary criteria for selecting a syntax. Each of the above points can
contribute to program clarity. The use of free format, mnemonic identifiers and conventional forms allows the programmer
to use notations which have their familiar meanings to put down his ideas and intentions in the order
and form that humans think about them, and to transfer skills he already
has to the solution of the problem at hand.
A simple uniform language reduces the number of cases which must be dealt with by anyone using the language. If programs are difficult for the translator
to parse, they will be difficult for people. Similar things should use the
same notations with the special case processing reserved for the translator and object machine.
The purpose of mnemonic identifiers and key words is to be informative and increase the
distance between lexical units of programs. This does not prevent the use of short identifiers and short key words
in the first place.
V.H.2. [NO SYNTAX EXTENSIONS]
The user will not be able to modify the source language syntax. Specifically, he will not be
able to modify operator hierarchies, introduce new precedence rules, define new key word forms or define
new infix operator precedence.
If the user can change the syntax of the language, then he can change the basic character and understanding of the language.
the distinction between semantic extensions and syntactic extensions is similar to that between being able to coin new words
in English or being able to move to another natural language. Coining words requires learning those new meanings
before they can be used, but at the same time increases
the power of the language for some application areas.
Changing the grammar (e.g., using French), however, undermines the basic
understanding of the language itself, changes the mode of expression, and
removes the commonalities which obtain between various specializations of the language.
Growth of a language through definition of new data and operations and the introduction
of new words and symbols to identify them is desirable, but there should be no provision
for changing the grammatical rules of the language. This requirement does not conflict with E4 and
does not preclude associating new meanings with existing infix operators.
V.H.3. [SOURCE CHARACTER SET]
The syntax of source language programs will be composable from a character set suitable for
publication purposes, but no feature of the language will be inaccessible
using the 64 character ASCII subset.
A common language should use notations and a character set convenient for communicating algorithms, programs,
and programming techniques among its users. On the other hand, the language should not require special equipment
(e.g., card readers and printers) for its use. The use of the 64 character ASCII subset will make the language
compatible with the federal information processing standard 64 character set, FIPS-1, which has been adopted by
the U.S.A. standard code for information interchange (USAASCII). The language definition
will specify the translation from the publication language into the restricted character set.
V.H.4. [IDENTIFIERS AND LITERALS]
The language definition will provide the formation rules for identifiers and literals. These will include
literals for numbers and character strings, and a break character for use internal to identifiers and literals.
Lexical units of the language should be defined in a simple uniform and easily understood manner. Some possible
break characters are the space (W, Dijkstra, Coding Examples in Chapter I, "Notes in Structure Programming," in Structured Programming
by O-J-Dahl, E.w. Dijkstra and C.A.R. Hoare,
Academic Press, 1972, & Thomas A. Standish, "A Structured Program to Play Tic-Tac-Toe," notes for information and
Computer Science 3 course at Univ. of California-Irvine, October 1974) (i.e., any number of spaces or end-of-line),
the underline and the tilde. The space cannot be used
if identifiers and user defined infix operators are lexically indistinguishable but, in such a case, the formal
grammar for the language would be ambiguous (see H1). A literal break character contributes
to the readability of programs and makes the entry of long literals less error prone.
With a space as a break character one can enter multipart (i.e., more than one lexical unit)
identifiers such as "REAL TIME CLOCK" or long literals, such as, "3.14159 26535 89793." Use
of a break can also be used to guarantee that missing quote brackets on character literals do not cause
errors which propagate beyond the next end-of-line. The language should require separate quoting of each line
of a long literal: "This is a long" "literal string".
V.H.5. [LEXICAL UNITS AND LINES]
There will be no continuation of lexical units across lines, but there will be a way to include object characters such
as end-of-line in literals strings.
Many elementary input errors arise at the end of lines. Programs are input on line oriented
media, but the concept of end-of-line is foreign to free format text. Most of the error prone aspects of
end-of-line can be eliminated by not allowing lexical units to continue
over lines. The sometimes undesirable effects of this restriction
can be avoided by permitting identifiers and literals to be composed from
more than one lexical unit (see H4), and by evaluating constant expressions at
compile time (see C4).
V.H.6. [KEY WORDS]
Key words will be reserved, will be very few in number, will be informative, and will not be usable in contexts where an
identifier can be used.
By key words of the language are meant those symbols and strings which have special meaning in the syntax
of programs. They introduce special syntactic forms such as are used for control structures and declarations,
or they are used as infix operators, or as some form of parenthesis. Key words will be few in number
because each new key word introduces another case in the parsing rules
and thereby adds to complexity in understanding the language, and because large
numbers of key words inconvenience and complicate the programmer's task of choosing informative
identifiers. Key words should be concise, but being informative is more important than being short.
A major exception is the key word introducing a comment; it is the comment and not its key word which should do the
informing. Finally, there will be no place in a source language program in which a key word
can be used in place of an identifier.
That is, functional form operations and special data items built into the language or accessible as a
standard extension will not be treated as key words but will be treated as any other identifier.
V.H.7. [COMMENT CONVENTIONS]
The source language will have a single uniform comment convention. Comments will be easily distinguishable
from code, will be introduced by a single (or possibly two) language defined characters, will permit
any combination of characters to appear, will be able to appear
anywhere reasonable in programs, will automatically terminate at end-of-line if not otherwise terminated, and will not prohibit
automatic reformatting of programs.
These are all obvious points which will encourage the use of comments in programs and avoid their error prone
features in some existing languages. Comments anywhere reasonable in a program will not be taken to mean
that they can appear internal to a lexical unit, such as an identifier, key word,
or between the opening and closing brackets of a character string.
One comment convention which nearly meets these criteria is to have a special quote character which
begins comments, and with either the quote or an end-of-line ending each comment. This allows
both embedded and line-oriented comments.
V.H.8. [UNMATCHED PARENTHESES]
The language will not permit unmatched parentheses of any kind.
Some programming languages permit closing parentheses to be omitted. If, for example, a program contained more "BEGINS" than "ENDS",
the translator might insert enough "ENDS" at the end of the program to make up the difference. This makes programs easier
to write because it sometimes saves writing several "ENDs" at the end of programs, and because it eliminates
all syntax errors for missing "ENDs." Failure to require proper parentheses matching makes it more difficult to write
Good programming practice requires that matching parentheses be included in programs whether or not they are required by the language.
Unfortunately, if they are not required by the language then there can be no syntax check to discover
where errors were made. The language will require full parentheses matching. This does not preclude syntactic features
such as "case x or s1, s2...sn end case" in which "end" is paired with a key word other than "begin." Nor does it
alone prohibit open forms such as "if-then-else-."
V.H.9. [UNIFORM REFERENT NOTATION]
There will be a uniform referent notation.
The distinction between function calls and data reference is one of representation, not of use. Thus, there will be no language
imposed syntactic distinction between function calls and data selection. If, for example,
a computed function is replaced by a lookup table, there should be no need to change the calling program.
This does not preclude the inclusion of more than one referent notation.
V.H.10. [CONSISTENCY OF MEANING]
No language defined symbols appearing in the same context will have essentially different meanings.
This contributes to the clarity and uniformity of programs, protects against psychological ambiguity
and avoids some error prone features of extant languages. In particular, this would exclude the use
of = to imply both assignment and equality, would exclude conventions
implying that parenthesized parameters have special semantics (as with PL/1 subroutines), and
would exclude the use of an assignment operator for other than assignment (e.g., left hand side
function calls). It would not, however, require different operator symbols for
integer, real or even matrix arithmetic since these are, in fact, special cases of the same abstract
operations, and would allow the use of generic functions
applicable to several data types.
V.I. DEFAULTS, CONDITIONAL COMPILATION, AND LANGUAGE RESTRICTIONS
V.I.1. [NO DEFAULTS IN PROGRAM LOGIC]
There will be no defaults in programs which affect the program logic. That is, decisions which affect program logic
will be made either irrevocably when the language is defined, or explicitly in each program.
The only alternative is implementation dependent defaults with the translator determining the meaning of programs.
What a program does should be determinable from the program and the defining documentation
for the programming language. This does not require that binding of all program
properties be local to each use. Quite the contrary. It would, for example, allow automatic definition of
assignment for all variables or global specification of precision. What it does require is that each decision
be explicit: in the language definition, global to some scope or local to each use. Omission of any
selection which affects the program logic will be treated as an error by the translator.
V.I.2. [OBJECT REPRESENTATION SPECIFICATION OPTIONAL]
Defaults will be provided for special capabilities affecting only object representation and
other properties which the programmer does not know or care about. Such defaults will always mean that the
programmer does not care which choice is made. The programmer will be able to override these defaults when necessary.
The language should be oriented to provide a high degree of management control and visibility to programs and toward self-documenting
programs, with the programmer required to make his decisions explicit. On the other hand, the programmer should
not be forced to overspecify his programs and thereby cloud their logic, unnecessarily eliminate opportunities for
optimization, and misrepresent arbitrary choices as essential to the program logic.
Defaults will be allowed, in fact encouraged, in don't care situations. Such defaults will include data
representation (see J4), open vs. closed subroutine calls (see J5), and
reentrant vs. nonreentrant code generation.
V.I.3. [COMPILE TIME VARIABLES]
The user will be able to associate compile time variables with programs. These will include
variables which specify the object computer model and other aspects of the object machine configuration.
V.I.4. [CONDITIONAL COMPILATION]
The source language will permit the use of conditional statements (e.g., case statements) dependent on the object
environment and other compile time variables. In such cases, the conditional will be evaluated at
compile time and only the selected path will be compiled.
An environmental inquiry capability permits the writing of common programs and procedures which are
specialized at compile time by the translator as a function of the
intended object machine configuration, or of other compile time variables (see I3).
This requirement is a special case of evaluation of constant expressions at compile time (see C4).
It provides a general purpose capability for conditional compilation.
V.I.5. [SIMPLE BASE LANGUAGE]
The source language will contain a simple, clearly identifiable base, or kernel, which houses all the power of the
language. To the extent possible, the base will be minimal with each feature providing a single unique capability
not otherwise duplicated in the base. The choice of the base will not detract from the efficiency,
safety, or understandability of the language.
The capabilities available in any language can be partitioned into two groups - those which are definable
within the base, and those which provide an essential primitive capability of the language.
The smaller and simpler the base, the easier the language will be to learn and use.
A clearly delineated base with features not in the base, defined in terms of the base,
will improve the ease and efficiency of learning, implementing and maintaining the language.
Only the base need be implemented to make the full source language capability available.
Base features will provide relatively low level, general purpose capabilities not yet specialized for
particular applications. There will be no prohibition on a translator incorporating specialized optimizations
for a particular extension. Any extension provided by a translator will, however, be definable within the base
language using the built-in definition facilities. Thus, programs using the extension will be
translatable by any compiler for the language, but not necessarily with the same object efficiency.
V.I.6. [TRANSLATOR RESTRICTIONS]
Language restrictions which are dependent only on the translator, and not on
the object machine, will be specified explicitly in the language definition.
Limits on the number of array dimensions, the length of identifiers, the number of nested parentheses levels in
expressions, or the number of identifiers in programs are determined by the translator and not by the
object machine. Ideally, the limits should be set so high that no program
(save the most abrasive) encounters the limits. In each case, however:
- some limit must be set,
- whatever the limit, it will impose on some and, therefore, must be known by the users of the
- letting each translator set its own limits means that
programs will not be portable,
- setting the limits very high requires that the translator be hosted only on large machines and
- quite low limits do not impose significantly on either the power of the language or the readability of programs.
Thus, the limits should be set as part of the language definition. They should be small enough that they do
not dominate the compiler, and large enough that they do not interfere with the usefulness of the language.
If they were set at, say, the 99 percent level, based on statistics from existing DoD computer programs,
the limits might be a few hundred for numbers of identifiers, and less than ten in the other cases mentioned above.
V.I.7. [OBJECT MACHINE RESTRICTIONS]
Language restrictions which are inherently dependent only on the object environment will not be built into
the language definition or any translator.
Limits on the amount of run time storage, access to specialized peripheral equipments, use of special hardware capabilities and
access to real time clocks are dependent on the object machine and configuration. The translator will report when a program
exceeds the resources or capabilities of the intended object machine, but will not build in arbitrary limits of its own.
V.J. EFFICIENT OBJECT REPRESENTATIONS AND MACHINE DEPENDENCIES
V.J.1. [EFFICIENT OBJECT CODE]
The language and its translators will not impose run time costs for unneeded or unused generality. They will be
capable of producing efficient code for all programs.
The base language and library definitions might contain features and capabilities which are not needed by everyone or, at least,
not by everyone all the time. The language should not force programs to require greater generality than they need. When a program
does not use a feature or capability, it should pay no run time cost for the feature being in the language
or library. when the full generality of a feature is not used, only the necessary (reduced) cost should be paid.
Where possible, language features (such as automatic and dynamic array allocation,
process scheduling, file management and I/O buffering) which require run time support packages should be provided
as standard library definitions and not as part of the base language.
The user will not have to pay time and space for support packages he does not use.
Neither will there be automatic movement of programs or data between main store and backing store which is not under program
control (unless the object machine has virtual memory with underlying
management beyond the control of all its users). Language features will result
in special, efficient object codes when their full generality is not used. A large number
of special cases should compile efficiently. For example, a program doing numerical calculations on
unsubscripted real variables should produce code no worse than FORTRAN. Parameter passing for
single argument routines might be implemented much less expensively than multiple argument routines.
One way to reduce costs for unneeded capabilities is to have a base language whose
data structures and operations provide a single capability which is composable and has a straight-forward implementation
in the object code of conventional architecture machines. If the base language components are easily composable, they can
be used to construct the specialized structures needed by specific applications.
If they are simple and provide a single capability, they will not force the use of
unneeded capabilities in order to obtain needed capabilities, and if they
are compatible with the features normally found in sequential uniprocessor digital computers with random access memory,
they will have near minimu, or at least low cost, implementation on many object machines.
V.J.2. [OPTIMIZATIONS DO NOT CHANGE PROGRAM EFFECT]
Any optimizations performed by the translator will not change the effect of the program.
More simply, the translator cannot give up program reliability and correctness, regardless of the excuse.
Note that for most programming languages there are few known safe optimizations, and many unsafe ones.
The number of applicable safe optimizations can be increased by making more information available to
the compiler, and by choosing language constructs which allow safe optimizations. This requirement allows optimization
by code motion, providing that motion does not change the effect of the program.
V.J.3. [MACHINE LANGUAGE INSERTIONS]
The source language will provide encapsulated access to machine dependent hardware
facilities, including machine language code insertions.
It is difficult to be enthusiastic about machine language insertions. They defeat the purpose of
machine independence, constrain the implementation techniques, complicate the diagnostics, impair the
safety of type checking, and detract from the reliability, readability, and modifiability of programs.
The use of machine language insertions is particularly dangerous in multiprogramming applications
because they impair the ability to exclude, "a priori," a large class of time-dependent bugs.
Rigid enforcement of scope rules by the compiler in real time applications is a powerful tool to ensure that one sequential
process will not interfere with others in an uncontrolled fashion. Similarly, when several independent
programs are executed in an interleaved fashion, the correct execution of each may depend on the
others not having improperly used machine language insertions.
Unfortunately, machine language insertions are necessary for interfacing special purpose devices, for accessing special
purpose hardware capabilities, and for certain code optimizations on time critical paths.
Here we have an example of Dijkstra's dilemma (see Section I.B.) in which the mismatch between high level language programming
and the underlying hardware is unacceptable, and there is no feasible way to reject the hardware. The
only remaining alternative is to "continue bit pushing in the old way, with all the
known ill effects." Those ill effects can, however, be constrained to the smallest possible perimeter in practice,
if not in theory.
The ability to enter machine language should not be used as an excuse to exclude otherwise
needed facilities from the HOL; the abstract description of programs in the HOL should not require
the use of machine language insertions. The semantics of machine language insertions will be determinable from the HOL definition
and the object machine description alone, and not dependent on the translator characteristics. Machine language insertions
will be encapsulated so they can be easily recognized, and so that it is clear which
variables and program identifiers are accessed within the insertion. The machine language insertions will be permitted
only within the body of compile time conditional statements (see I4)
which depend on the object machine configuration (see I3).
They will not be allowed interspersed with executable statements of the source language.
V.J.4. [OBJECT REPRESENTATION SPECIFICATIONS]
It will be possible within the source language to specify the object representation of composite data structures.
These descriptions will be optional and encapsulated and will be distinct from the
logical description. The user will be able to specify the time/space trade-off to the translator. If not specified,
the object representation will be optimal as determined by the translator.
It is often necessary to give detailed specifications of the object data representations to obtain
maximum density for large data files to meet format requirements imposed by the hardware of peripheral
equipment, to allow special optimizations on time critial paths, or to ensure compatibility when transferring
data between machines.
It will be possible to specify the order of the fields, the width of fields, the presence of don't care fields,
and the position of word boundaries. It will be possible to associate source language identifiers
(data or program) with special machine addresses. The use of machine dependent characteristics of the object
representation will be restricted, as with machine dependent code (see J3).
When multiple fields per word are specified, the compiler must generate some form of shift and mask operations
for source program references, and assignments to those variables (i.e., fields). As with machine-language
insertions, object data specifications should be used sparingly, and the language features for their use must be
spartan, not grandiose.
V.J.5. [OPEN AND CLOSED ROUTINE CALLS]
The programmer will be able to specify whether calls on a routine are to have an open or closed
implementation. An open and a closed routine of the same description will have identical semantics.
The use of inline open procedures can reduce the run time execution costs significantly in some cases.
There are the obvious advantages in eliminating the parameter passing, in avoiding the saving of return marks,
and in not having to pass arguments to and from the routine.
A less obvious, but often more important, advantage in saving run time costs is the ability to execute
constant portions of routines at compile time and, thereby, eliminate time and space for those portions of the
procedure body at run time. Open routine capability is especially important for machine language insertions.
The distinction between open and closed implementation of a routine is an efficiency consideration, and
should not affect the function of the routine. Thus, an open routine will differ from a syntax macro in that:
- its global environment is that of its definition, and not that
of its call and
- multiple occurrences of a formal value (i.e., read only)
parameter in the body have the same value.
If a routine is not specified as either open or closed, the choice will be optimal as determined by the translator.
VI. CHARACTERISTICS NEEDED FOR OTHER ASPECTS OF THE COMMON LANGUAGE EFFORT
The material reported in this chapter was generated by the Services at the same time as the technical
characteristics, but is concerned with the translators' support software,
documentation, training, standard, application libraries, management policy, and procurement
practices for the common language and its use. These issues are important, while mistakes and
oversights in the technical characteristics
can guarantee failure of the common language effort, success is not guaranteed no matter
how technically meritorious the resulting language. Success can only be guaranteed by close attention
to a variety of nontechnical issues, including those considered below.
Several of these issues, including those of implementation, documentation, and support with either directly
or indirectly affect the acceptability of candidate languages. As with the need for the technical characteristics
for the common language, the issues raised here are often not resolved at the most detailed level. Until
more detailed characteristics of the language come into focus, there is no rationale with which to
resolve all these issues in detail.
VI.A. PROGRAM ENVIRONMENT
VI.A.1. [OPERATING SYSTEM NOT REQUIRED]
The language will not require that the object machine have an operating system. When the object machine
does have an operating system or executive program, the hardware/operating system combination will be
interpreted as defining an abstract machine which acts as the object machine for the translator.
A language definition cannot dictate the architecture of existing object machines, whether defined entirely in hardware or
in a hardware/software combination. It can provide a source language representation of all the needed
capabilities and attempt to choose these so they have an obvious and efficient translation in the object machines.
VI.A.2. [PROGRAM ASSEMBLY]
The language will support the integration of separately written modules into an operational program.
Separately written modules in the form of routines and type definitions are necessary for the management of large software
efforts and for effective use of libraries. The user will be able to cause anything in any accessible
library to be inserted into his program. This is a requirement for separate definition, but not necessarily for
separate compilation. The decision as to whether separately defined program modules are to be maintained in source or object
language form is a question of implementation efficiency, will be a local
management option, and will not be imposed by the language definition. The trade-offs involved are complicated by other
requirements for type checking of parameters (see C6), for open subroutines
(see J5), for efficient object
representations (see J1), and for constant expression evaluation at compile time (see C4).
In general, separate compilation increases the difficulty and expense of the interface validations needed
for program safety and reliability, and detracts from object program efficiency by resolving many of the
optimizations otherwise possible at the interfaces but, at the same time, it reduces the cost and
complexity of compilation.
VI.A.3. [SOFTWARE DEVELOPMENT TOOLS]
A family of programming tools an aids in the form of support packages including linkers, loaders and debugging systems will
be made available with the language and its translators. There will be a consistent, easily used user interface for these tools.
The time has passed in which a programming language can be considered in isolation from its programming environment. The
availability of programming tools which need not be developed and/or supported by individual projects is a
major factor in the acceptability of a language. There is no need to restrict the kinds or form of support
software available in the programming environment, and continued development of new tools should be encouraged and
made available in a competitive market. It is, however, desirable that tools be developed in their own
source language to simplify their portability and maintainability.
VI.A.4. [TRANSLATOR OPTIONS]
A variety of useful options to aid generation, test, documentation and modification of programs will be provided as
support software available with the language, or as translator options. As a minimum, these will include
program editing, post mortem analysis and diagnostics, program reformatting for standard indentations,
and cross-reference generation.
There will be special facilities to aid the generation, test, documentation and
modification of programs. The "best" set of capabilities and their proper form are not currently known.
Since nonstandard translator options and availability of nonstandard software tools and aids do not
adversely affect software commonality, the language definition and standards will not dictate
arbitrary choices. Instead, the development of language associated tools and aids will be
encouraged within the constraint of implementing and supporting the source language as defined.
Tools and debugging aids will be source language oriented.
Some of the translator options which have been suggested, and may be useful, include the following.
Code might be compiled for assertions which would give run time warnings when the value of the assertion predicate is
false. It might provide run time tracing of specified program variables. Dimensional analysis might be done on
units of measure specification. Special optimizations might be invoked. There might be capability for
timing analysis and conformity with local conventions.
The user might be able to inhibit code generation. There might be facilities for compiling program
patches and for controlling access to language features. The translator might provide a listing of
the number of instructions generated aginst corresponding source inputs and/or an estimate of their execution times. It
might provide a variety of listing options.
VI.A.5. [ASSERTIONS AND OTHER OPTIONAL SPECIFICATIONS]
The source language will permit inclusion of assertions, assumptions, axiomatic definitions of data types,
debugging specifications, and units of measures in programs. Because many assertional methods are not yet
powerful enough for practical use, nor sufficiently well developed for standardization, they will have
the status of comments.
There are many opinions on the desirability, usefulness, and proper form for each of these specifications.
Better program documentation is needed, and specifications of these kinds may help. Specifications
also introduce the possibility of automated testing, run time verification of predicates, formal
program proofs, and dimensional analysis. The language will not prohibit inclusion of these forms
of specification if and when they have become for practical use in programs. Assertions, assumptions, axiomatic
definitions and units of measure in source language programs should be enclosed in special brackets and
should be treated as interpreted comments -- comments which are delimited by special comment brackets, and which may
be interpreted during translation or debugging to provide units analysis, verification of assertions
and assumptions, etc. -- but whose interpretation would be optional to translator implementations.
VI.B.1. [NO SUPERSET IMPLEMENTATIONS]
No implementation of the language will contain source language features which are not defined in the
language standard. Any interpretation of a language feature not explicitly permitted by the language
definition will be forbidden.
This guarantees that use of programs and software subsystems will not be restricted to a particular site
by virtue of using their unique version of the language. It also represents a commitment to freezing
the source language, inhibiting innovations and growth in the form of
the source language, and confining the base language to the current state of the art in return for stability,
wider applicability of software tools, reusable software, greater software visibility, and
increased payoff for tool building efforts. It does not, however, disallow library definition optimizations
which are translator unique.
VI.B.2. [NO SUBSET IMPLEMENTATIONS]
Every translator for the language will implement the entire base language. There will be no subset
implementations of the language.
If individual compilers implement only a subset of the language, there is no chance for software commonality.
If a translator does not implement the entire language, it cannot give its users access to standard
supported libraries, or to applications programs implemented on some other translator.
Requiring that the full language be implemented will be expensive only if the base language is large,
complex, and nonuniform. The intended source language product from this effort is a small,
simple, uniform base language with the specialized features, support packages, and complex features relegated
to library routines not requiring direct translator support. If simple, low cost translators are not
feasible for the selected language, then the language is too large and complex to be standardized, and
the goal of language commonality will not be achievable.
VI.B.3. [LOW-COST TRANSLATION]
The translator will minimize compile time costs. A goal of any translator for the language will be low cost translation.
Where practical and beneficial, the user will have control over the level of optimization applied to his programs.
The programmer will have control over the tradeoffs between compile time and run time costs.
The desire for small, efficient translators which can be hosted by machines with
limited size and capability should influence the design of the base language against inclusion of
unnecessary features and towards systematic treatment of features which are included. The goal will be
effective use of the available machines, both in object execution and translation, and not maximal speed of translation.
Translation costs depend not only on the compiler, but [also on] the language design.
Both the translator and the language design will emphasize low cost translation but, in an environment
of large and long-lived software product, this will be secondary to requirements for reliability and maintainability.
Language features will be chosen to ensure that they do not impose costs for unneeded generality, and
that needed capabilities can be translated into efficient object representations. This means
that the inherent costs of specific language features, in the context of the total language, must be understood
by the designers, implementors and users of the language.
One consequence should be that trivial programs compile and run in trivial time. On the other hand, significant optimization
is not expected from a minimal cost translation.
VI.B.4. [MANY OBJECT MACHINES]
Translators will be able to produce code for a variety of object machines. The machine independent part of
translators might be built independent of the code generators.
There are currently no common, widely used computer in the DoD. There are at least 250 different models of
commercial machines in use in DoD, with many more specialized machines. A common language must be
applicable to a wide variety of models and sizes of machines. Translators might be written so they can
produce object code for several machines. This reduces the proliferation of translators,. and makes the full
power of an existing translator available at the cost of producing an additional code generator.
VI.B.5. [SELF-HOSTING NOT REQUIRED]
The translator need not be able to run on all the object machines. Self-hosting is not required, but is often
The DoD operational programming environment includes many small machines which are unable to support
adequately the design, documentation, test, and debugging aids necessary for the development of
timely, reliable or efficient software. Large machine users should not be penalized for the restrictions
of small machines when a common language is used. On the other hand, the size of machines which can host
translators should be kept as small as possible by avoiding unnecessary generality in the language.
VI.B.6. [TRANSLATOR CHECKING REQUIRED]
The translator will do full syntax checking, will check all operations and parameters for type compatibility,
and will verify that all language imposed semantic restrictions on the source programs are met.
It will not automatically correct erros detected at compile time.
The purpose of source language redundancy and avoidance of error prone language features is reliability.
The price is paid in programmer inconvenience in having to specify his intent in greater detail.
The payoff comes when the translator checks that the source program is internally
consistent, and adheres to its authors' stated intentions.
There is a clear trade-off between error avoidance and programming ease; surveys conducted in the
Services show that the programmers, as well as managers, will opt for error avoidance over ease when
given the choice.
The same choice is dictated by the need for well documented, maintainable software.
VI.B.7. [DIAGNOSTIC MESSAGES]
The translator will produce compile time explanatory diagnostic error and warning messages.
A suggested set of error and warning situations will be provided as part of the language definition.
The translator will attempt to provide the maximal useful feedback to its user. Diagnostic messages will not be
coded, but will be explanatory and in source language terms.
Translators will continue processing and checking after errors have been found, but should be careful not
to generate erroneous messages because of translator confusion.
The translator will always produce code to cause a run time exception condition upon any attempt to
execute those parts of the program. Warnings will be generated when a source language construct is
exceptionally expensive to implement on the specified object machine. A suggested set of diagnostic messages,
provided as part of the language definition, contributes to commonality in the implementation and use of the language.
The discipline of designing diagnostic messages key to the design may also uncover pitfalls in the language
design and, thereby, contribute to a more precise and better understood language description.
VI.B.8. [TRANSLATOR INTERNAL STRUCTURE]
The characteristics of translator implementations will not be dictated by the language definition or standards.
The adoption of a common language is a commitment to the current state of the art for programming languge design
for some duration. It does not, however, prevent access to new software and hardware technology, new techniques, and new management
strategies which do not impact the source language definition.
In particular, innovation should be encouraged in the development of translators for a common language,
providing they implement exactly the source language as defined.
Translators, like all computer programs, should be written in expectation of change.
VI.B.9. [SELF-IMPLEMENTABLE LANGUAGE]
Translators for the language will be written in their own source language.
There will be at least one implementation of the translator in its own language which does all parsing and
compile-time checking and procedures an output suitable for easy translation to specific object
If the language is well-defined and uniform in structure, a self-description will contribute to understanding of the language.
The availability of the machine independent portion of a translator will make the full power of the language available to any
object machine at the cost of producing an additional code generator (and that cost may be high), and reduces
the likelihood of incompatible implementations.
With translators written in their own source language, they are automatically available on any of their object
machines, providing the object machine has sufficient resources to support a compiler.
VI.C. LANGUAGE DEFINITION, STANDARDS AND CONTROL
VI.C.1. [EXISTING LANGUAGE FEATURES ONLY]
The language will be composed from features which are within the state of the art, and any design or redesign
which is necessary to achieve the needed characteristics will be conducted as an engineering design
effort, and not as a research project.
The adoption of a common language can be successful only if it makes available a modern programming language
compatible with the latest software technology and is compatible with "best" current programming practice,
but the design and implementation of the language should not require additional research or require use of untried ideas.
State-of-the-art cannot, however, be taken to mean that a feature has been
incorporated in an operational DoD language and used for an extended period, or DoD will be forever tied to the technology of
FORTRAN-like languages; but there must be some assurances through analysis and use that its benefits and
deficiences are known. The large and more complex the structure, the more analysis and use that should be required.
Language design should parallel other engineering design efforts in that it is a task of consolidation, and
not innovation. The language designer should be familiar with the many choices in semantic and syntactic features
of language and should strive to compose the best of these into a consistent structure congrous with the needed characteristics.
The language should be composed from known semantic features and familiar notations, but the use of a
proven feature should not necessarily impose that notation.
The language must not just be a combination of existing features which satisfy the individual requirements,
but must be held together by a consistent and uniform structure which acts to minimize the number of concepts, consolidates
divergent features, and simplifies the whole.
VI.C.2. [UNAMBIGUOUS DEFINITION]
The semantics of the language will be defined unambiguously and clearly. To the extent a formal definition
assists in attaining these objectives, the language's semantics will be specified formally.
A complete and unambiguous definition of a common language is essential. Otherwise, each translator will resolve the ambiguities
and fill in the gaps in its own unique way. There are currently a variety of methods for formal specification
of programming language semantics, but it remains a major effort to produce a rigorous formal description,
and the resulting products are of questionable practical value. The real value in attempting a formal definition
is that it reveals incomplete and ambiguous specification. An attempt will be made to provide a formal
definition of any language selected, but success in that effort should not be requisite to its selection.
Formal specification of the language might take the form of an axiomatic definition, use of the Vienna Definition
Language, definition by an interpreter (a la Lisp), or use of some other formal semantic system.
VI.C.3. [LANGUAGE DOCUMENTATION REQUIRED]
The user documentation of the language will be complete, and will
include both a tutorial introductory description and a formal, in-depth description.
The language will be defined as if it were the machine level language of an abstract digital computer.
The language should be intuitively correct, and easily learned and understood by its potential users.
The language definition might include an Algol-60 like description (P. Naur (Ed.), "Revised Report on
the Algorithmic Language Algol-60," Communication of the A.C.M., Vol.6, No.1, January 1963, p.1-17.)
with the source language syntax given in BNF or some other easily understood metalanguage, and the corresponding
semantics given in English. As with the descriptions of digital computer hardware, the semantics and
syntax of each feature must be defined precisely and unambiguously.
The action of any legal program will be determinable from the program and the language description alone.
Any computation which can be described in the language will ultimately draw only on capabilities
which are built into the language. No characteristics of the source language will be dependent on the
idiosyncrasies of its translators.
The language documentation will include syntax, semantics and examples of each language construct, listings of
all key words and language defined defaults. Examples shall be included to show the intended use of
language features, and to illustrate proper use of the language. Particularly expensive and inexpensive
constructs will be pointed out. Each document will identify its purpose and prerequisites for its use.
VI.C.4. [CONTROL AGENT REQUIRED]
The language will be configuration managed throughout its total life cycle, and will be controlled at the DoD
level to ensure that there is only one version of the source language, and that all
translators conform to that standard.
Without controls, a hopefully common language may become another umbrella under which new languages proliferate
while retaining the same name. All compilers will be tested and certified for conformity to the standard
specification and freedom from known errors prior to their release for use in production projects.
The language manager will be on the OSD staff, but a group within the Military Departments or Agencies
might act as the executive agent. A configuration control board will be instituted with user representation,
and chaired by a member of the OSD staff.
VI.C.5. [SUPPORT AGENT REQUIRED]
There will be identified support agent(s) responsible for maintaining the translators and for associated
design, develop, debugging and maintenance aids.
Language commonality is an essential step in achieving software commonality, but the real benefits accrue when projects and contractors
can draw on existing software with assurance that it will be supported, when systems can build from off the
shelf components or, at least, with common tools, and when efforts can be spent to expand existing
capabilities, rather than building from scratch. Support of common, widely used tools and aids should be
provided independent of projects if common software is to be widely used. Support should be on a DoD-wide
basis, with final responsibility resting with a stable group, or groups, of qualified in-house personnel.
VI.C.6. [LIBRARY STANDARDS AND SUPPORT REQUIRED]
There will be standards and support agents for common libraries, including application-oriented libraries.
In a given application of a programming language, three levels of the system must be learned and use:
the base language, the standard library definitions used in that application area, and the local application programs.
Users are responsible for the local application programs and local definitions, but not for the language and its
libraries which are used by many projects and sites. A principal user might act as agent for an entire application area.
- David A. Fisher, "Automatic Data Processing Costs in the Defense Department,"
Institute for Defense Analyses Paper P-1046, October 1974.
- Space and Missle Systems Organization, AFSC, Information Processing/Data Automation Impllication of
Air Force Command and Control Requirements in the 1980's (CCIP-83), Vol. IV, Technology Tranes: Software,
October 1973, AD 919267L.
- Malcolm H. Currie, Defense Research and Engineering, in Memorandum to the Assistant Secretaries of the
Military Departments (R&D), Subject: DoD High Order Programming Language, January 28, 1975.