A delicate balance is necessary in the handling of variables and constants. Reliability and security demand that the two concepts be clearly separated. On the other hand it is convenient if a variable declaration can be changed into a constant declaration by a very simple alteration of the program text. Ada meets these two goals by having two distinct but related forms of declaration for the two concepts. Thus the following object declaration:
C : constant REAL := 300_000.0;
declares a constant, whereas the following object declaration declares a variable with an initial value:
SPEED : REAL := C/1500.0;
The adjective constant which appears in the declaration of a constant states that the value of this object must not be altered after its initialization. By writing this adjective, the programmer expresses his intent in an explicit manner and requests the assistance of the compiler in forbidding attempts to alter the value - whether by accident, by mistake, or deliberately.
Following Algol 68 however, the adjective constant does not mean that the initial value must be known at compilation time (that is, in Ada terminology, the initial value expression need not be static).
For example, a function to determine whether a given integer number is prime may declare an upper bound on divisors:
function PRIME(X : INTEGER) return BOOLEAN is UPPER_BOUND : constant INTEGER := INTEGER(SQRT(X)); begin ... end PRIME;
and clearly the value of this upperbound, although constant for a given call of the function, will be computed in terms of the actual parameter of the function, and hence dynamically.
Good programming style in Ada will systematically emphasize constants, even for short texts where the danger of accidental alterations would be very slight. For example, an Ada formulation of the classical procedure to exchange the values of two variables will emphasize the fact that the temporary variable - OLD_LEFT - is indeed a constant:
procedure EXCHANGE(LEFT, RIGHT : in out INTEGER) is OLD_LEFT : constant INTEGER := LEFT; begin LEFT := RIGHT; RIGHT := OLD_LEFT; end;
An initialization is required in the case of a constant. For variables it is allowed but not required. Allowing initialization of a variable in its declaration enables one to ensure that the initial state of variables is well-defined. Furthermore, this avoids long sequences of initialization assignment statements, which are divorced from the declarations and hence hard to locate.