[Oberon] Why no enumeration types?

Diego Sardina dsar at eml.cc
Mon Jul 26 12:48:54 CEST 2021


On Mon, Jul 26, 2021, at 11:14 AM, Timothy Pearson wrote:
> 
> I guess I’m missing something fundamental. To me, this is a perfect 
> illustration of the benefits of enumerations — that the interface 
> change forces dependencies to be rebuilt.
> 

You are missing two points: binary compatibility and the constant nature of the enumeration types.

Enumeration types are group of entities that don't change ( = immutable) but they are misused for things that change or grow over the time, such error codes and messages.

You must be able to add a new error code and message in your minor version of library without breaking binary compatibility with programs that are using your library. You can't tell everyone "hey, there is a new error code, rebuild all your programs".

> 
> The difference is they have a type, they are not (conceptually) integer 
> constants. Any procedure with a colour parameter could not be 
> accidentally passed a value of 99. Any procedure with a numeric 
> parameter could not accidentally be passed a value of Green.
> 

True, the fact that they are integers is an implementation detail.
But what is different with record instances then?

MODULE Days;

TYPE 
   Day* = POINTER TO DayDesc;
   [...]

VAR 
   sun*, mon*, tue*, wed*, thu*, fri*, sat* : Day;
   [...]

MODULE daytest;

IMPORT Days;

VAR today: Days.Day;

BEGIN
   today := Days.mon;
   [...]

In Oberon-07 global variables are readonly outside the module, in Oberon-2 you should use the readonly export.

Here Days.Day is a limited type, it can be null or one of the instances declared in the global space of the module (they should not be allocated outside the module, but only declared).
If you want to mimic the enumeration type, you can also define a Day.Next() procedure to iterate over the days or a Day.Name() to get the associated string.

The nature of days is immutable, in the case of an Error type you can add a new instance here without breaking clients.

MODULE InterestingLib;

TYPE
   Error* = POINTER TO ErrorDesc;
   [...]

VAR
   (* Error instances *)
   error0001*: Error;
   error0002*: Error;
   [...]
   error0172*: Error; (* added in 26/07/2021 *)

BEGIN
  error0001 := InitError(1, "File not found");
  [...]

--
Diego Sardina


More information about the Oberon mailing list