That's very interesting. Subranges is a feature that I have always liked in Pascal and other languages.
You do have any more detail about the reasoning why Wirth thought this feature was "not worth it" for Oberon? Were programmers not using this feature in Pascal and Modula-2? Did Wirth consider it more noise or complexity in those languages?
"Subrange types were introduced in Pascal (and adopted in Modula) for two reasons: (1) to indicate that a variable accepts a limited range of values of the base type and to allow a compiler to generate appropriate guards for assignments, and (2) to allow a compiler to allocate the minimal storage space needed to store values of the indicated subrange. This appeared desirable in connection with packed records. Very few implementations have taken advantage of this space saving facility, because the additional compiler complexity is very considerable. Reason 1 alone, however, did not appear to provide sufficient justification to retain the subrange facility in Oberon."
"... was the observation that in a growing number of programs the indiscriminate use of enumerations (and subranges) had led to a type explosion that contributed not to program clarity but rather to verbosity."
Instead the proposed solution is to use SET.
"With the absence of enumeration and subrange types, the general possibility of defining set types based on given element types appeared as redundant. Instead, a single, basic type SET is introduced, whose values are sets of integers from 0 to an implementation-defined maximum."
It seems subranges could be something of a double-edged sword. Too many enumerations and subranges in a program adds complexity. However, without them I presume the guards need to be coded manually elsewhere in the program.
It's really fascinating to see the reasoning a programming language designer makes when choosing what feature to include - or exclude.
> without them I presume the guards need to be coded manually elsewhere in the program.
That is my conclusion as well, reading the Oberon manual a SET seems just to be a normal set but for integers only, thus you have to manually check if your integer value is part of the set within the procedure itself, however that check will be a runtime check, not a compile time check if you had a proper enumeration type (I assume). And to my understanding Oberon doesn't have any error handling, so how exactly you would promote a out of range check to an error is unknown to me.
I guess that you would probably want to define constants to fill the set with, thus adding some more noise.
CONST RED = 1;
CONST GREEN = 2;
CONST BLUE = 3;
SET COLORS = (RED, GREEN, BLUE)
So you can use it a procedure call
draw(RED);
Compare to Pascal enumeration
type COLORS = (RED, GREEN, BLUE);
It feels like Wirth was somewhat obsessed with the idea of type extension with Oberon, it should be possible to import any module (program) and extend it without restrictions and enumerations created a problem how you would extend it.
If you have a color module defining the enumeration COLORS together with a bunch of procedures accepting COLORS, then in another custom module you want extend COLORS with the color YELLOW plus some YELLOW specific procedures.
But if you pass an extended enumeration E' to a procedure that accepts the base enumeration E, which should be legal similar how you can pass T' as T, the procedure would receive illegal values, in this case YELLOW. What you need to do instead is create your own CUSTOM_COLORS enumeration, manually include every color from COLORS and add YELLOW, and when calling procedures within the colors module type cast from CUSTOM_COLORS to COLORS enumeration. Perhaps this is the type explosion Wirth was referring to.
Out of range would still be problem if you extend a SET, but you avoid type casts.
This is how I interpret Wirth reluctance to enumerations (and subranges).
You do have any more detail about the reasoning why Wirth thought this feature was "not worth it" for Oberon? Were programmers not using this feature in Pascal and Modula-2? Did Wirth consider it more noise or complexity in those languages?