Sample programs thus far have contained a number of instances where some value was typed literally. This has been true of all the items written out by WriteString statements thus far. In
WriteString ("Hi there.")
the quoted string Hi there is called a string literal. Likewise in the assignment
counter := 1;
the value 1 on the right hand side of the assignment statement is a cardinal literal.
An entity specified by its value, rather than by a pre-declared name, is called a literal.
More accurately, the symbols in the string Hi there and the digit in the numeral 1 are not values themselves, but symbolic encodings of those values. (The values themselves are mental abstractions, and 1 is a symbol or numeral for the idea, not the idea itself.) Technically that is, literals are also names. This observation prompts the following more accurate (if perhaps harder to follow) definition:
A literal is any entity whose name is an encoding of its value.
firstInt := 5; secondInt := firstInt + 7; character := 'C';
In these examples, the symbols 5, 7, and 'C' are all literals. The compiler convert such literals into the correct form necessary to do the assignment in each case. Note that there is a type implied in a literal, even if the type is ambiguous. Thus, some literal assignments can be made more than one way; others cannot be done at all. If card is of type cardinal, and int is of type integer, then:
card := 7; int := 7;
are both correct, as the literal 7 can be interpreted as either type. However,
card := -7;
is clearly incorrect, and the compiler can catch this error without having to postpone checking until the program is run.
These were discussed in general terms in section 1.6.5 along with variables. Suppose that in the course of the sample program, Powers the exponent was always equal to five. Rather than read this number in from the keyboard every time, or even write the variable assignment
exponent := 5;
in the program, it may be desirable to name it as a constant.
A Modula-2 constant is an identified value that remains the same throughout a program; that is, it is not subject to later re-assignment.
Constants are declared in a manner similar to variables. Unlike variables, they simultaneously receive a (fixed) value. For instance, to use the above number as a constant, the identifier exponent would be removed from under the VAR declaration and placed under a CONST declaration instead. The syntax for CONST declarations is shown in Figure 2.8.
CONST (* Another reserved word *) exponent = 5; VAR base, counter, result: CARDINAL;
This has two potential advantages: the constant is changed into the correct internal form for the computer's use only once rather than several times. This may gain some speed but, more important, if it is later decided that the number in question should be six rather than five, it need be changed only once up at the beginning of the program, rather than several times throughout, with the possibility of missing one or two instances.
Once constants have been declared, they can be used wherever the original literal could be used because the type of the constant is checked before making an assignment. If it is not compatible, an error is generated. Moreover, the type does not need to be explicitly declared in the CONST statement because it will be assigned automatically. One cannot therefore get away with writing character := 'C' + amount where character is of type CHAR and amount equals 5 (a constant), because the compiler records that amount can only be of type INTEGER or CARDINAL. The compiler also will automatically treat all negative whole number constants as being of type INTEGER. Thus,
CONST number = -4; ten = 10; space = " ";
creates the INTEGER constant number, the CARDINAL/INTEGER (whole number type) constant ten, and the CHAR constant space.
NOTE: The identifiers of constants, unlike those of variables, are equated to their values rather than being assigned to them. This might not seem like much of a difference, especially when the same kinds of names can be given to both, but Modula-2 forces the distinction to be made by requiring the "=" symbol instead of the ":=" operator. Confusing these two is a common beginners' error.