OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Понедельник, 23 Июнь, 2025 10:22

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 69 ]  На страницу 1, 2, 3, 4  След.
Автор Сообщение
 Заголовок сообщения: Почему убрали перечисления.
СообщениеДобавлено: Четверг, 02 Март, 2006 16:48 

Зарегистрирован: Суббота, 28 Январь, 2006 00:10
Сообщения: 52
Откуда: г. Киров
Меня давно интересует вопрос, на который я не могу найти подробного ответа: почему убрали перечисления из оберона?
Сам Вирт в своей лекции в России сказал по этому поводу примерно так: с ними (перечислениями) были какие то проблемы, я не помню точно какие, и мы решили их убрать.

Единственное объяснение которое я знаю: они мешают расширять типы (нельзя добавлять новые перечисления). Но на самом деле эта проблема решается, а в Zonnon перечисления были вновь добавлены (как и многое другое :?).

Что по этому поводу знает многоуважаемый All?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Почему убрали перечисления.
СообщениеДобавлено: Четверг, 02 Март, 2006 18:35 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Алексей Елин писал(а):
Сам Вирт...

...писал, что (статья "От Модулы к Оберону"):
Цитата:
Тип перечисление слишком простое средство, чтобы выйти из-под контроля. Однако, оно не позволяет распространять расширяемость за пределы модуля. И либо нужно ввести средство для расширения типа перечисление, либо же от типа перечисление надобно отказаться. Причина, по которой мы выбрали второй путь — путь радикального решения — кроется в том, что во все возрастающем числе программ непродуманное использование перечислений (и диапазонов) ведет к демографическому взрыву среди типов, что, в свою очередь, ведет не к ясности программ, а к ее многословию. В связи с использованием экспорта и импорта перечисления приводят к исключению из правил, и согласно ему импорт идентификатора типа также приводит к автоматическому импорту всех связанных с типом идентификаторов констант. Это исключение нарушает концептуальную простоту и создает для реализаторов языка неприятные проблемы.

Короче, использование обычных констант есть слишком простое средство чтобы программист смог запутаться, поэтому вводить перечисления просто незачем. То есть перечисления следовало бы ввести если бы программисты (часто) путались с обычными константами. Но программисты (обычно) не путаются с обычными константами, поэтому вводить перечисления причины нет.

Алексей Елин писал(а):
Но на самом деле эта проблема решается

Не решается.
Вот был модуль:
Код:
DEFINITION Colors;
  CONST red = 1; green = 2
END Colors.

Потом мы его заменили на такой:
Код:
DEFINITION Colors;
  CONST red = 1; green = 2; blue = 3
END Colors.

(добавили еще одну константу не изменив старые). Этот новый модуль заменяем со старым модулем. Никакие старые программы перекомпилировать не надо. Но, если бы мы добавили еще одну константу в тип-перечисление, то мы бы изменили этот тип. Отныне, это был бы уже совсем другой тип. Все старые модули, которые использовали старый тип не захотели бы работать с новым типом (абсолютно все сто тыщь мильёнов старых модулей надо было бы перекомпилировать).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 23 Май, 2007 11:58 

Зарегистрирован: Вторник, 22 Май, 2007 15:38
Сообщения: 238
Откуда: Питер
По сравнению с Модулой-2 (например), где перечисления есть, в Обероне, как мне кажется, усложняется индексация массивов.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 23 Май, 2007 12:19 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2461
Откуда: Россия, Томск
GameHunter писал(а):
По сравнению с Модулой-2 (например), где перечисления есть, в Обероне, как мне кажется, усложняется индексация массивов.

Неплохо бы пример под такое заявление. А то что-то не понятно, что может быть проще, чем индексация всегда с нуля и всегда до LEN()-1.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 23 Май, 2007 13:42 

Зарегистрирован: Вторник, 22 Май, 2007 15:38
Сообщения: 238
Откуда: Питер
Перечисление подразумевает не только множество констант, но и свои границы. Таким образом, чтобы в Обероне организовать перечисление, нужно не только по одной константе на каждый элемент перечисления, но и одну или две дополнительные константы для границ. Только в этом случае добавление новых элементов в перечисление не приведёт к изменению индексации массивов. Однако, за границами в Обероне надо следить вручную, что не удобно и потенциально может привести к ошибке.

Модула-2:
Код:
DEFINITION Colors;
  TYPE
    Color=(Red,Green,Blue);
    ColorProperty=ARRAY [Color] of ...
END Colors

...

FOR c:=MIN(Colors.Color) TO MAX(Colors.Color) DO
...
    prop[c]:=...
...
END;


Оберон:
Код:
MODULE Colors;
  CONST
    Red*=0;
    Green*=1;
    Blue*=2;
    MaxColor*=Blue;
  TYPE
    ColorProperty=ARRAY MaxColor+1 of ...
END Colors

...

FOR c:=0 TO Colors.MaxColor DO
...
    prop[c]:=...
...
END;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 23 Май, 2007 13:43 

Зарегистрирован: Вторник, 22 Май, 2007 15:38
Сообщения: 238
Откуда: Питер
О, пардон, про LEN()-1 не заметил :oops: . Вопрос снимается.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 23 Май, 2007 13:49 

Зарегистрирован: Вторник, 22 Май, 2007 15:38
Сообщения: 238
Откуда: Питер
Хотя, при объявлении типа массив неудобство всё-таки сохраняется.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 23 Май, 2007 14:43 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2461
Откуда: Россия, Томск
GameHunter писал(а):
Хотя, при объявлении типа массив неудобство всё-таки сохраняется.

Да, неудобство есть. Есть и другие неудобства, например, следующая процедура возвращает номер дня недели, соответствующий указанной дате:
Код:
PROCEDURE DayOfWeek* (IN d: Date): INTEGER;

Если возвращаемое значение = 0, то это понедельник (как у нас) или воскресенье (как у них)? Надо сравнивать с константой Monday либо Sunday. Вопрос: где объявлены нужные константы? В этом же модуле? Не обязательно. Надо искать, рыть документацию. Это во-первых.

А во-вторых, никто не помешает этот результат сравнить с любой другой целочисленной константой, например, Sundae (десерт такой). Представьте, что мы пишем программу, которая помогает составить меню для ресторанчика на неделю, и возможные блюда мы объявили в виде констант. Как видите, опечатка не так уж невозможна, а компилятор промолчит, спокойно сравнивая десерт с днем недели.

Чтобы избежать подобных ошибок можно делать объектные обертки для перечислимых типов, я где-то на этом форуме приводил пример реализации. Это будет несколько непривычно, но работать будет, читабельность повысит и от ошибок - застрахует.

Кстати, в компиляторе XDS поддерживаются перечислимые типы, причем в обероновских исходниках. Там динамической загрузки нет, перечислимые типы контролировать гораздо проще. Да, там при изменении перечислимого типа производится перекомпиляция всех зависимых модулей, но там это не проблема.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 23 Май, 2007 14:55 
Администратор

Зарегистрирован: Вторник, 15 Ноябрь, 2005 01:14
Сообщения: 4722
Откуда: Россия, Орёл
Похоже всё-таки нужно нам делать FAQ... э-э-э... Wiki :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 23 Май, 2007 19:52 

Зарегистрирован: Вторник, 22 Май, 2007 15:38
Сообщения: 238
Откуда: Питер
Цитата:
Чтобы избежать подобных ошибок можно делать объектные обертки для перечислимых типов, я где-то на этом форуме приводил пример реализации. Это будет несколько непривычно, но работать будет, читабельность повысит и от ошибок - застрахует.


Пример поискал, не нашёл. Приведите, пожалуйста, более конкретную ссылку.

Цитата:
Кстати, в компиляторе XDS поддерживаются перечислимые типы, причем в обероновских исходниках.


Да. Но, к сожалению, связанные с перечислениями множества там в оберон не прикрутили :(


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 23 Май, 2007 21:43 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2461
Откуда: Россия, Томск
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? Практически или теоретически? Что-то разрабатывали на нем?


Последний раз редактировалось Александр Ильин Четверг, 24 Май, 2007 06:26, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 24 Май, 2007 00:28 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Александр Ильин писал(а):

Код:
MODULE Dates;

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



Возможно, вместо LIMITED имелось в виду ABSTRACT? А то непонятно, зачем тогда расширять тип-то.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 24 Май, 2007 06:31 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2461
Откуда: Россия, Томск
info21 писал(а):
Возможно, вместо LIMITED имелось в виду ABSTRACT? А то непонятно, зачем тогда расширять тип-то.

Ой, вы правы. Не доглядел. Дело в том, что в первоначальном варианте было ABSTRACT, а когда сюда переносил решил сделать LIMITED. Поправил пост наверху.

Дело в том, что абстрактные записи допускают расширение и создание расширенных экземпляров, а у меня задача стояла не допустить появление несанкционированных объектов этого типа. Клиент не может создавать новые дни недели, поскольку процедуры модуля Dates, куда они попадут в качестве параметров, не будут знать, что с ними делать.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 24 Май, 2007 08:05 

Зарегистрирован: Вторник, 29 Ноябрь, 2005 21:41
Сообщения: 1030
Неплохо. Но лучше, всё-таки, если такой механизм (после стандартизации) появится в языке.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 24 Май, 2007 09:32 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
Гм, какой механизм? какая стандартизация?
Я могу ошибаться, но:
1) стандарт - это сообщение о языке. Он уже есть и меняться не будет. На то это и стандарт.
2) Если Вы имеете в виду появление перечислений, то их тоже, поверьте, убрали не просто так. Это нужно для большей независимости между модулями-компонентами. Перечисление - тип. Чем больше зависимостей от типов, тем больше модулей нужно перекомпилировать, если тип поменялся (Вы добавили или убрали одно значение из перечисления).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 24 Май, 2007 09:50 

Зарегистрирован: Вторник, 29 Ноябрь, 2005 21:41
Сообщения: 1030
Евгений Темиргалеев писал(а):
Гм, какой механизм? какая стандартизация?
Механизм был указан чуть выше. Как уже было сказано Александром, при изменении значений "перечисления" DayOfWeek его тип остается прежним. Со всеми вытекающими отсюда последствиями.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 24 Май, 2007 10:12 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
Перечисления в таком виде... мне кажется что такое решение не будет подходящим для всех задач. А средства языка - средства универсальные... Я сразу даже не предположил, что Вы предлагаете именно такую реализацию вставить в язык. :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 24 Май, 2007 10:27 

Зарегистрирован: Воскресенье, 28 Май, 2006 22:12
Сообщения: 1693
Александр Ильин писал(а):
Посмотрел, это было в закрытой части форума. Скопирую сюда, пусть будет достоянием общественности.

С этого места - поподробней, пожалста! :о)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 24 Май, 2007 10:40 

Зарегистрирован: Вторник, 29 Ноябрь, 2005 21:41
Сообщения: 1030
Евгений Темиргалеев писал(а):
Я сразу даже не предположил, что Вы предлагаете именно такую реализацию вставить в язык. :)
Если Вы помните, я не предлагал вставить в язык именно такую реализацию. Лишь только обладающую указанными Александром свойствами. И то после разбора всех альтернатив ( читай стандартизации ). А в каких случаях она не подойдет?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 24 Май, 2007 10:52 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2461
Откуда: Россия, Томск
Евгений Темиргалеев писал(а):
Перечисления в таком виде... мне кажется что такое решение не будет подходящим для всех задач. А средства языка - средства универсальные... Я сразу даже не предположил, что Вы предлагаете именно такую реализацию вставить в язык. :)

Безусловно, не для всякой задачи. Например, таким способом удобно задавать небольшие перечисления, но не диапазоны типа TYPE Int = 0..32768. А если нет диапазона, то и массив ARRAY Int OF ... тоже создать не получится.

Еще таким способом не удастся задать субтип для контроля физической величины, чтобы не сложить ненароком скорость с высотой. В этом случае лучше сделать объектные обертки ценой потери простоты записи (придется использовать height.Add(height2) место INC(height, height2)).

Я за концептуальную чистоту Оберона: если что-то можно реализовать уже имеющимися средствами, не нужно вводить новых "для удобства". Пусть лучше в голове будет порядок. Есть в этом какая-то своя... романтика, что ли.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 69 ]  На страницу 1, 2, 3, 4  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2025, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB