OberonCore https://forum.oberoncore.ru/ |
|
Структурная совместимость синонимов https://forum.oberoncore.ru/viewtopic.php?f=29&t=6871 |
Страница 1 из 1 |
Автор: | adimetrius [ Среда, 16 Ноябрь, 2022 14:01 ] |
Заголовок сообщения: | Структурная совместимость синонимов |
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; Это бы позволило компилятору проводить дополнительные проверки и обращать внимание на потенциальные ошибки, в данном примере - ошибку масштабирования координат. |
Автор: | adimetrius [ Среда, 16 Ноябрь, 2022 14:07 ] |
Заголовок сообщения: | Re: Структурная совместимость синонимов |
Можно провести такие аналогии: INTEGER - это абстрактное математическое понятие числа. Код: TYPE Velocity = INTEGER; (* это физическое понятие скорости, т.е. это уже не совсем число, хотя моделируется числом; к числу еще добавляется понятие единицы измерения *) Time = INTEGER; (* - это физическое понятие времени, тоже не просто число, а число и единица измерения *) Spatium = INTEGER; (* путь - число и единица измерения *) VAR s: Spatium; v: Velocity; t: Time; Напрямую v, s и t несовместимы, как при решении задач в физике, так и в программе; присваивание между ними бессмысленно. Неплохо было бы, если бы компилятор мог такое выявлять. Что скажете? |
Автор: | Comdiv [ Четверг, 17 Ноябрь, 2022 01:51 ] |
Заголовок сообщения: | Re: Структурная совместимость синонимов |
adimetrius писал(а): Тогда, пожалуй, и типы-синонимы тоже - структурно, а не номинально совместимы: Нет, ведь, TYPE не вводит новые типы сам по себе, а всего лишь "Описание типа связывает идентификатор с типом", поэтому ссылаясь в правой части на уже имеющееся имя он вводит не синоним, а ещё одно имя-псевдоним. А создаются типы соответствующими конструкторами - ARRAY и RECORD. Разница тонкая, но существенная. Для создания нового типа-синонима(или почти синонима) в Oberon нет специальной конструкции, потому что для этого всего-то и нужно объявить массив из одного элемента или запись с одним элементом. Разве что вернуть из функции значение такого типа нельзя.Код: TYPE Color = INTEGER; VAR col: Color; w: INTEGER; BEGIN col := 7; col := w; Код: 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; |
Автор: | Comdiv [ Четверг, 17 Ноябрь, 2022 02:08 ] |
Заголовок сообщения: | Re: Структурная совместимость синонимов |
adimetrius писал(а): Напрямую v, s и t несовместимы, как при решении задач в физике, так и в программе; присваивание между ними бессмысленно. Неплохо было бы, если бы компилятор мог такое выявлять. Что скажете? Для языка общего назначения это, вероятно, излишнее усложнение, а если нет, то конструкторы типов никто, по-прежнему, не отменял. И для них можете задать всё, что угодно, если хватит сил, например, указать, что s/t - осмысленно и равно v, v/t - это а, но s/(t*t) нельзя, потому что t^2 бессмысленно. Можно ещё попытаться описать все варианты связей на свете. Например, сумма координат точек - это тоже бессмыслица, и вроде бы не нужна, но вот сумма координат точек, поделённой пополам - это координата точки, равноудалённо лежащей между ними и, вроде бы, нужна. Потом можно начать сводить разные модули от разных авторов и столкнуться ещё и с одинаковыми, но несовместимыми величинами.Это всё хорошо в каком-то смысле, но не попадает в принцип Парето. |
Автор: | Trurl [ Четверг, 17 Ноябрь, 2022 07:12 ] |
Заголовок сообщения: | Re: Структурная совместимость синонимов |
Comdiv писал(а): Нет, ведь, TYPE не вводит новые типы сам по себе, а всего лишь "Описание типа связывает идентификатор с типом", поэтому ссылаясь в правой части на уже имеющееся имя он вводит не синоним, а ещё одно имя-псевдоним. Но ведь синонимы и есть разные имена для того же. |
Автор: | Comdiv [ Четверг, 17 Ноябрь, 2022 11:34 ] |
Заголовок сообщения: | Re: Структурная совместимость синонимов |
Имеете ввиду, что "псевдоним" - это синоним "синонима"? Синонимы лишь похожи по смыслу, но, как правило, не тождественны. Так и тут, вводя подтип мы сообщаем, что это почти то же самое кроме ещё кое-чего, но в Oberon такого нет. Связывание же с именем не делает ничего, кроме связывания с именем, сколько бы этих имён не было. "Разница тонкая, но существенная". А в Компонентном Паскале есть даже специальное пояснение Цитата: Одинаковые типы [Same types]
Две переменные a и b с типами Ta и Tb имеют одинаковый тип, если 1. Ta и Tb оба обозначены одним и тем же идентификатором типа, или 2. Ta описан в описании типа вида Ta = Tb, или 3. a и b появляются в одном списке идентификаторов в описании переменных, полей записи или формальных параметров. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |