OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Вторник, 29 Ноябрь, 2022 18:08

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




Начать новую тему Ответить на тему  [ Сообщений: 6 ] 
Автор Сообщение
СообщениеДобавлено: Среда, 16 Ноябрь, 2022 14:01 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 545
Comdiv писал(а):
Comdiv писал(а):
Процедурные типы - это единственное средство, опирающееся на структурную, а не именную совместимость по типам.
Не совсем точно, потому что в Oberon структурная совместимость также у открытых массивов, допустимых в формальных параметрах, а в Компонентном Паскале и для указателей:
Цитата:
Правила совместимости для указателей были ослаблены и упрощены. Теперь указатели совместимы по структуре; то есть два указательных типа, имеющих общий базовый тип, являются совместимыми. Это может быть полезно в основном в сигнатурах процедур, где раньше было невозможно использовать функции, подобные следующей:

PROCEDURE P (p: POINTER TO ARRAY OF INTEGER)


Тогда, пожалуй, и типы-синонимы тоже - структурно, а не номинально совместимы:
Код:
TYPE Color = INTEGER;
VAR col: Color; w: INTEGER;
BEGIN
  col := 7; col := w;

Синонимы позволяют сделать замысел программиста более явным, и потому программу - понятнее.
Из-за структурной совместимости они не добавляют проверок.
И из-за структурной совместимости ими удобно пользоваться - иначе пришлось бы приводить 7 и w к типу Color.

А что если определить правила совместимости иначе: синоним и его базовый тип совместимы, но требуется явное приведение между синонимами одного базового типа?
Код:
TYPE
  Pixels = INTEGER;
  Units = INTEGER;

(* Pixels и INTEGER совместимы, Units и INTEGER совместимы, Pixels и Units несовместимы, требуют явного приведения *)

PROCEDURE (rd: Rider) DrawRect (l, t, r, b: Pixels);
PROCEDURE (f: Frame) DrawRect (l, t, r, b: Units);

PROCEDURE P (f: Frame; rd; Rider; x, y: Units);
BEGIN
  f.DrawRect(0, 0, x, y);
  rd.DrawRect(0, 0, x DIV f.unit, y DIV f.unit);
  rd.DrawRect(0, 0, x, y)  (* недопустимо, ошибка компиляции *)
END P;

Это бы позволило компилятору проводить дополнительные проверки и обращать внимание на потенциальные ошибки, в данном примере - ошибку масштабирования координат.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 16 Ноябрь, 2022 14:07 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 545
Можно провести такие аналогии: INTEGER - это абстрактное математическое понятие числа.
Код:
TYPE
  Velocity = INTEGER;   (* это физическое понятие скорости, т.е. это уже не совсем число, хотя моделируется числом; к числу еще добавляется понятие единицы измерения *)
  Time = INTEGER;   (* - это физическое понятие времени, тоже не просто число, а число и единица измерения *)
  Spatium = INTEGER;  (* путь - число и единица измерения *)

VAR s: Spatium; v: Velocity; t: Time;


Напрямую v, s и t несовместимы, как при решении задач в физике, так и в программе; присваивание между ними бессмысленно. Неплохо было бы, если бы компилятор мог такое выявлять. Что скажете?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 17 Ноябрь, 2022 01:51 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1382
Откуда: Киев
adimetrius писал(а):
Тогда, пожалуй, и типы-синонимы тоже - структурно, а не номинально совместимы:
Код:
TYPE Color = INTEGER;
VAR col: Color; w: INTEGER;
BEGIN
  col := 7; col := w;
Нет, ведь, TYPE не вводит новые типы сам по себе, а всего лишь "Описание типа связывает идентификатор с типом", поэтому ссылаясь в правой части на уже имеющееся имя он вводит не синоним, а ещё одно имя-псевдоним. А создаются типы соответствующими конструкторами - ARRAY и RECORD. Разница тонкая, но существенная. Для создания нового типа-синонима(или почти синонима) в Oberon нет специальной конструкции, потому что для этого всего-то и нужно объявить массив из одного элемента или запись с одним элементом. Разве что вернуть из функции значение такого типа нельзя.

Код:
TYPE
  Pixels = ARRAY 1 OF INTEGER;
  Units = ARRAY 1 OF INTEGER;

(* Pixels и INTEGER почти совместимы, Units и INTEGER почти совместимы, Pixels и Units несовместимы, требуют явного приведения *)

PROCEDURE (rd: Rider) DrawRect (l, t, r, b: Pixels);
PROCEDURE (f: Frame) DrawRect (l, t, r, b: Units);

PROCEDURE P (f: Frame; rd; Rider; x, y: Units);
VAR px, py: Pixels;
BEGIN
  f.DrawRect(Unit0, Unit0, x, y);
  f.UnitToPixel(x, px);  f.UnitToPixel(y, py);
  rd.DrawRect(Pixel0, Pixel0, px, py);
  rd.DrawRect(Pixel0, Pixel0, x, y)  (* недопустимо, ошибка компиляции *)
END P;


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 17 Ноябрь, 2022 02:08 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1382
Откуда: Киев
adimetrius писал(а):
Напрямую v, s и t несовместимы, как при решении задач в физике, так и в программе; присваивание между ними бессмысленно. Неплохо было бы, если бы компилятор мог такое выявлять. Что скажете?
Для языка общего назначения это, вероятно, излишнее усложнение, а если нет, то конструкторы типов никто, по-прежнему, не отменял. И для них можете задать всё, что угодно, если хватит сил, например, указать, что s/t - осмысленно и равно v, v/t - это а, но s/(t*t) нельзя, потому что t^2 бессмысленно. Можно ещё попытаться описать все варианты связей на свете. Например, сумма координат точек - это тоже бессмыслица, и вроде бы не нужна, но вот сумма координат точек, поделённой пополам - это координата точки, равноудалённо лежащей между ними и, вроде бы, нужна. Потом можно начать сводить разные модули от разных авторов и столкнуться ещё и с одинаковыми, но несовместимыми величинами.

Это всё хорошо в каком-то смысле, но не попадает в принцип Парето.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 17 Ноябрь, 2022 07:12 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1421
Comdiv писал(а):
Нет, ведь, TYPE не вводит новые типы сам по себе, а всего лишь "Описание типа связывает идентификатор с типом", поэтому ссылаясь в правой части на уже имеющееся имя он вводит не синоним, а ещё одно имя-псевдоним.

Но ведь синонимы и есть разные имена для того же.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 17 Ноябрь, 2022 11:34 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1382
Откуда: Киев
Имеете ввиду, что "псевдоним" - это синоним "синонима"? Синонимы лишь похожи по смыслу, но, как правило, не тождественны. Так и тут, вводя подтип мы сообщаем, что это почти то же самое кроме ещё кое-чего, но в Oberon такого нет. Связывание же с именем не делает ничего, кроме связывания с именем, сколько бы этих имён не было. "Разница тонкая, но существенная".

А в Компонентном Паскале есть даже специальное пояснение
Цитата:
Одинаковые типы [Same types]
Две переменные a и b с типами Ta и Tb имеют одинаковый тип, если
1. Ta и Tb оба обозначены одним и тем же идентификатором типа, или
2. Ta описан в описании типа вида Ta = Tb, или
3. a и b появляются в одном списке идентификаторов в описании переменных, полей записи или формальных параметров.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 6 ] 

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


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

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


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

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