Pascal was intended, in part, to be a simple language to implement. Some of the design decisions reflecting this are
- Declarations/definitions must be given in a strict order (labels, constants, types, variables, routines); they can't be mixed. (The order allows for the constants to be used in subrange types, and for the types to be used in variable declarations.)
- Every entity must be declared in some way before use.
- The symbol denoting a subrange is
..
, not...
, which can simplify lexical analysis (all punctuator tokens are at most two characters long.) - Arrays must have constant bounds.
- The language does not have the concept of a constant expression, so that
5..10
is OK but3+2..10
is not. - Pointers are restricted to record types created with
new
.
However, there are also some bewildering decisions (as someone who has recently implemented a parser and semantic analyzer for Pascal):
ThePeople have rightfully pointed out that this isn't actually unusual. Omitting parameter specification is just weird to me, although maybe it's because I'm accustomed to C's convention for prototypes and declarations, where the information is repeated. For what it's worth, Donald Knuth dislikes it as well.forward
convention, where parameters are omitted at the actual point of definition, is beyond bizarre. And it requires keeping around more parameter information than usual in order to process the body of the subsequent non-forward
declaration in the correct lexical environment.- Standard procedures and functions can take special arguments not allowed elsewhere in the language, such as width specifiers, and many of them are variadic.
- Statement labels are numeric.
This question is about the last point: Why have numeric labels? If labels were symbolic, then you could use your existing data structures for maintaining the current environment of identifiers for labels as well.
Putting the language in its historical context makes the choice no less odd:
The one part of Algol 60 that most people seem to have agreed was a mistake was the existence of numeric labels (in addition to symbolic labels—at the very least, Pascal sticks with only one kind). Here is what Dahlstrand, Goteborg, and Naur have to say about this in Algol Bulletin AB10.3.
The admission of integers as labels will produce some peculiar possibilities, like the following:
procedure Pop(Q); procedure Q; begin … Q(3); … end;
procedure Pip(A); label A; begin … go to A; … end;
procedure Pap(B); real B; begin … q ≔ B; end;
Pop(Pap);
Pop(Pip);Evidently the number 3 appearing within the body of procedure Pop will in the first of these two procedure statements be used as a number, while in the second it will be used as a label.
We do not want to suggest any formal change of the language, since in spite of the peculiarity the above example is well defined. On the other hand we do want to disrecommend the use of integers in labels in actual programs. We would like to see them die from disuse. That we do not accept them in our translators goes without saying.
Even Randell and Russell's Algol 60 Implementation, which otherwise goes to extraordinary lengths to implement the “hard parts” of a then-complex language, does not discuss the handling of numeric labels except at the very end; their compiler accepted only symbolic labels.
Such atrocities as Pop/Pip/Pap aren't possible in Pascal, but regardless, every other Algol derivative known to me uses symbolic labels.
forward
is kind of an issue fix in hindsight to allow the rare case of alternating recursion, otherwise not compatible with the idea of having everything defined before usage. We all know how much Pascal teachers love to use recursion :)) Numeric labels are a solution of essentially the same issue: being able to handle something that hasn't been defined). By using numbers the compiler can assume that they are labels and nothing else and assign according attributes in advance.label 1,2;
.