> -- GameHunter писал(а):
> Пример поискал, не нашёл. Приведите, пожалуйста, более конкретную ссылку.
Посмотрел, это было в закрытой части форума. Скопирую сюда, пусть будет достоянием общественности. Пример реализации типа "день недели" для модуля Dates.

## Код:
```
MODULE Dates;

TYPE 
  DayOfWeek* = POINTER TO LIMITED RECORD 
    index-: INTEGER 
  END; 

  VAR 
    monday-, tuesday-, wednesday-, thursday-, friday-, saturday-, sunday-: DayOfWeek; 
    daysOfWeek: ARRAY 7 OF DayOfWeek; 

  PROCEDURE GetDayOfWeek* (IN d: Date): DayOfWeek;
    (** Берем дату и определяем день недели *)
  BEGIN
    IF ... THEN RETURN monday
    ELSIF ... THEN RETURN tuesday
    ...
    END
  END GetDayOfWeek;

  PROCEDURE IndexToDayOfWeek* (index: INTEGER): DayOfWeek;
    (** Возвращаем день недели с указанным номером *)
  BEGIN
    RETURN daysOfWeek[index]
  END IndexToDayOfWeek;

<...>

  PROCEDURE NewStdDOW (index: INTEGER; OUT dow: DayOfWeek);
    (** Создаем день недели и связываем с индексом *)
  BEGIN
    NEW(dow);
    dow.index := index;
    daysOfWeek[index] := dow
  END NewStdDOW; 

BEGIN 
  NewStdDOW(0, monday);
  NewStdDOW(1, tuesday);
  NewStdDOW(2, wednesday);
  NewStdDOW(3, thursday);
  NewStdDOW(4, friday);
  NewStdDOW(5, saturday);
  NewStdDOW(6, sunday);
END Dates.
```


Что имеем в результате? Переменные monday..sunday экспортированы только для чтения и инициализированы при запуске, т.е. для клиентов являются константами. Тип DayOfWeek (LIMITED) не является расширяемым, и экземпляры объектов этого типа за переделами модуля Dates создать невозможно, значит полный контроль над предметной областью у нас есть, а число "предметов" равно числу созданных "констант".

Что может клиентский код? Передавать константы в качестве параметров и получать их в качестве выходного значения с полной статической и динамической проверкой типов. Сравнивать значение переменной с константами (равно или не равно). Благодаря необязательному, но в данном случае реализованному, полю index (экспорт только для чтения) может задаваться отношение порядка, то есть, можно проверять переменную относительно константы на больше-меньше.

Одновременно с этим модуль Dates может безболезненно дополнить список констант, что не потребует перекомпиляции клиентского кода. Если нужно по индексу дня недели быстро найти нужную константу типа DayOfWeek, можно использовать процедуру IndexToDayOfWeek. Массив daysOfWeek не экспортирован, чтобы избежать перекомпиляции клиентов при увеличении его размера.

По сути дела, получается, что у нас те же самые целочисленные константы, но в объектной обертке, гарантирующей правильный тип.

Читабельность: процедура GetDayOfWeek однозначно может быть сопоставлена с LIMITED-типом и read-only переменными, что дает узнаваемый паттерн реализации перечисления.

Все это плод моей фантазии, с удовольствием выслушаю критику и замечания. Илья Ермаков что-то говорил по поводу отсутствия литералов и дженериков, но я его не понял, а он не пояснил.

PS: В языках Oberon и Oberon-2 такое реализовать с достаточной степенью уверенности невозможно по причине отсутствия LIMITED-типов.

> -- GameHunter писал(а):
> Да. Но, к сожалению, связанные с перечислениями множества там в оберон не прикрутили
О, вы знакомы с XDS? Практически или теоретически? Что-то разрабатывали на нем?