Standardization (ISO) endorsement of the ANSI standard in 1987. The actual design work was performed by a design team, with review by a panel of experts and the interested public at large.
Major concerns in the design of Ada 83 were reliability, maintainability, human engineering, and efficiency. Human engineering refers to choosing keywords, syntax, and semantics to maximize readability, while trying to minimize "surprise" and error-prone constructs. For example, all control flow constructs have a distinct "end" marker (e.g., "end if," "end loop"), and all program units allow the name of the unit to be repeated (and the compile-time to be checked) at the end marker. Parameters may be specified as "in," "out," or "in out" to indicate the direction of information flow upon subprogram call. Formal parameter names may be used at the call point to identify unambiguously the association between formal and actual parameters.
Ada 83 supports strong type checking, extended to provide strong distinctions between otherwise structurally equivalent numeric types, as well as between otherwise structurally equivalent array types and pointer types. Ada 83 is unusual in that it allows the programmer to distinguish two same-sized integer types as representing distinct abstractions, and to specify that an array is meaningfully indexed by one, but not the other, or that a subprogram can meaningfully be passed by one, but not the other. For example, the two integer type declarations
type Month_Number is range 1..12
type Hour_Number is range 1..12
introduce two distinct integer types, and the fact that they have identical ranges does not alter the fact that they are distinguishable at compile-time when used as array indices, subprogram parameters, and record components. The compiler will detect the use of a value of one type when the other is expected. Furthermore, a change to one, such as switching Hour_Number to be range 0.23, does not have an unintended effect on some other abstraction.
Ada 83 supports data abstraction, modularity, and information hiding through a module construct called a "package" and through "private" types, types whose internal structure is hidden from code outside the defining package. Objects, subprograms, and any other language entity may be declared in the private part or body of a package, thereby hiding it from external access, and allowing revision during maintenance without disturbing external clients of the package.
Program units may be separately compiled while preserving full compile-time consistency checking across units. All program units may have a separate specification and body, allowing the physical configuration control of interfaces to allow productive parallel development of large systems, and enabling interface integrity to be verified before, rather than after, the code is developed.
Packages and subprograms may be defined as "generic" units, which are parameterized by types, objects, and subprograms. Such generic units must be explicitly instantiated with appropriate actual parameters prior to use. Like other units, generic units have a separate specification and body. When a generic unit is compiled, it is checked for legality. Further checks are performed when the unit is instantiated.
Ada 83 defines a complete set of run-time consistency checks to enforce range constraints on numeric types, index constraints on array types, and "discriminate" constraints on other composite types. In addition, all pointers are default initialized to null, and checked for null prior to dereferencing. Ada 83 defines an ability to raise and handle run-time exceptions. The predefined run-time checks all raise such run-time exceptions, allowing the programmer to write fault-tolerant code that catches unanticipated software problems, and performs appropriate recovery or disciplined shutdown actions.
Ada 83 includes a standard multithreading model, with a rendezvous construct to support inter threading communication and synchronization. Explicit delays are supported, as is timed