Naming things: const and type
Turning a number into a name with const, giving a type a short name of your own with type, and keeping both in the order the compiler expects.
const gives a value a name
A const block names a value that will not change: PassMark = 70;. From then on the name can be used anywhere the value could be, and the meaning of the program is written where a reader looks for it.
The value is fixed at compile time, so the compiler can use it for things that must be known before the program runs: the size of an array, for instance. array[1..Slots] is legal only because Slots is a constant.
Assigning to a constant is a compile error. That is the point of using one: a name that cannot drift is a name you can trust in ten places at once.
The name also documents the intent. PassMark says why 70 is there; the literal 70 says only that someone typed it. When the rule changes, a reader can find the name and be sure the change reaches every use.
type gives a shape a name
A type block names a shape: TScore = integer; says the new name means the old type, and TScoreList = array[1..Slots] of TScore; builds a bigger shape out of smaller ones.
The name is not a new kind of value and adds no behaviour; the compiler treats TScore as an integer everywhere. What it adds is a place to change: rewrite the one line and every declaration that uses it follows.
This is also how the array size and the type stay in step. Because Slots is a constant, the array cannot be three slots in one place and five in another.
A named type is also the place to hang a comment about what the values mean. TScore can say that it is a mark out of a hundred; a bare integer cannot. The compiler ignores the note, and the next reader does not.
The order of the blocks
The declaration part of a program reads in a familiar order: const, then type, then var, then the routines. A constant may be used by a type, a type by a variable, and nothing may use a name that has not been declared above it.
Keeping the blocks in that order is a habit worth having. It is the order the language is described in, it is the order a reader expects, and it means a name is always explained before the place that needs it.
A constant, a type, a variable
program Main;
const
Slots = 3;
type
TList = array[1..Slots] of integer;
var
values: TList;
i: integer;
begin
for i := 1 to Slots do
values[i] := i * 10;
writeln('Filled ', Slots, ' of ', high(values));
end.What the compiler does with a constant
The compiler substitutes the value of a const wherever the name appears; there is no storage and no lookup at run time. That is why a constant can appear in positions that must be settled before the program exists, such as an array bound or another constant expression. It is also why assigning to one is not a runtime no-op but a compile error.
A type alias is a name for the same type, not a new kind of value. TScore and integer are interchangeable everywhere, so a routine that takes a TScore will accept an integer and vice versa. The alias pays for itself when the shape is long, like an array type, or when the one line might change later; it is not a guard against passing the wrong number.
A worked change of one constant
Suppose a program uses the number 3 in six places: the array bound, two loops and three reports. Changing the class size means finding all six, and missing one produces an array that holds three values while a loop reads four. Replace the number with Slots = 3 and the six places become one declaration plus six names.
Now change Slots to 4. The array type grows, the loops that use Slots or high(values) follow, and the compiler rejects any place that still assumes three. That is the value of a constant: not that it saves typing, but that it turns a scattered edit into one edit the compiler can check.
Three declaration mistakes to watch for: declaring a type that uses a constant before the const block, assigning to a constant in the body, and expecting a type alias to reject a plain value of the base type. The first two stop the build; the third does not, because aliases are compatible by design.
Try these next
- Add a
constfor the pass mark in the first example and use it in the condition. - Change
Slotsto 4, add the fourth score, and check that the count follows. - Rename
TScoretoTMarkeverywhere in the first example and watch the compiler point at the first place you missed.
A pass mark and a named array type
Run it, then change `PassMark` to 80 and to 60, and predict how many pass each time. Then change `Slots` to 4 and see what breaks.
A constant is not a variable with a fixed starting value. It is replaced at compile time, so there is nothing to assign to, and the error arrives before the program runs.
A grid sized by two constants
Run it, then change `Cols` to 2 and predict both printed numbers. Add a fifth column only by changing the constant.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
What happens if the body tries to assign to a constant?
