OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Вторник, 27 Сентябрь, 2022 04:20

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




Начать новую тему Ответить на тему  [ Сообщений: 15 ] 
Автор Сообщение
 Заголовок сообщения: Проверка типов оператором IS
СообщениеДобавлено: Вторник, 13 Сентябрь, 2022 07:50 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 17
Прошу вашей помощи в понимании следующего вопроса. Есть вот такой пример:
Код:
    MODULE TestExt;
    IMPORT Log;
    TYPE
       pbas=POINTER TO bas;
       bas=EXTENSIBLE RECORD
                a:INTEGER;
             END;
       pras=POINTER TO ras;
       ras=RECORD(bas)
                b:REAL;
             END;
    VAR
       a:pbas;
       b:pras;
    BEGIN
       NEW(a);
       NEW(b);
       a:=b;
       IF a^ IS ras THEN
                          Log.String("Проверка по типу");
       ELSE
       END;
    END TestExt.


При компиляции выдаётся ошибка Guarded or tested variable is neither a pointer nor a VAR- or IN-parameter record.
Проверка по указателю ошибок компиляции не вызывает:
Код:
MODULE TestExt;
IMPORT Log;
TYPE
   pbas=POINTER TO bas;
   bas=EXTENSIBLE RECORD
            a:INTEGER;
         END;
   pras=POINTER TO ras;
   ras=RECORD(bas)
            b:REAL;
         END;
VAR
   a:pbas;
   b:pras;
BEGIN
   NEW(a);
   NEW(b);
   a:=b;
   IF a IS pras THEN
                      Log.String("Проверка по указателю");
   ELSE
   END;
END TestExt.


Почему для проверки по типу записи необходимо делать процедуру с параметрами VAR или IN ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проверка типов оператором IS
СообщениеДобавлено: Вторник, 13 Сентябрь, 2022 14:22 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1354
Откуда: Киев
AlexBogy писал(а):
Почему для проверки по типу записи необходимо делать процедуру с параметрами VAR или IN ?
Не совсем так, такой необходимости нет. Дело в другом - в языке была сделана попытка сделать недопустимыми бессмысленные проверки, которые всегда имеют одно и то же значение. В большинстве случаев для записей проверка имеет смысл только для ссылок, поставляющие данные извне, которые неявным образом задаются VAR и IN -параметрами. Отсутствие возможности проверки типа для разыменованного указателя - это побочный эффект такого ограничения и его можно считать упущением языка, так как здесь она тоже осмысленна. Это некритично, так как в таких случаях всегда можно проверить тип по указателю, не прибегая к разыменованию, хотя и может потребоваться объявить именованный указатель на соответствующую запись, если он не был предоставлен с самого начала.

Код:
MODULE TestExt; IMPORT Log;
TYPE
  bas=EXTENSIBLE RECORD a:INTEGER  END;
  ras=RECORD(bas) b:REAL; END;
VAR
  a:POINTER TO bas; b:POINTER TO ras;

PROCEDURE Go*;
TYPE pras = POINTER TO ras;(* Нужен исключительно для проверки IS *)
BEGIN
  NEW(b);
  a:=b;
  IF a IS pras THEN
    Log.String("a^ is ras"); Log.Ln
  END
END Go;

END TestExt.


Это, скорее, для раздела Почему в Обероне сделано так?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проверка типов оператором IS
СообщениеДобавлено: Вторник, 13 Сентябрь, 2022 15:48 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 17
Comdiv писал(а):
AlexBogy писал(а):
Почему для проверки по типу записи необходимо делать процедуру с параметрами VAR или IN ?
Не совсем так, такой необходимости нет. Дело в другом - в языке была сделана попытка сделать недопустимыми бессмысленные проверки, которые всегда имеют одно и то же значение. В большинстве случаев для записей проверка имеет смысл только для ссылок, поставляющие данные извне, которые неявным образом задаются VAR и IN -параметрами. Отсутствие возможности проверки типа для разыменованного указателя - это побочный эффект такого ограничения и его можно считать упущением языка, так как здесь она тоже осмысленна. Это некритично, так как в таких случаях всегда можно проверить тип по указателю, не прибегая к разыменованию, хотя и может потребоваться объявить именованный указатель на соответствующую запись, если он не был предоставлен с самого начала.

Код:
MODULE TestExt; IMPORT Log;
TYPE
  bas=EXTENSIBLE RECORD a:INTEGER  END;
  ras=RECORD(bas) b:REAL; END;
VAR
  a:POINTER TO bas; b:POINTER TO ras;

PROCEDURE Go*;
TYPE pras = POINTER TO ras;(* Нужен исключительно для проверки IS *)
BEGIN
  NEW(b);
  a:=b;
  IF a IS pras THEN
    Log.String("a^ is ras"); Log.Ln
  END
END Go;

END TestExt.


Это, скорее, для раздела Почему в Обероне сделано так?


Спасибо вам за ответ. По поводу бессмысленных проверок с заранее известным результатом - можно ли вот такой пример считать примером бессмысленных проверок:

Код:
MODULE TestExt;
IMPORT Log;
TYPE
   bas=EXTENSIBLE RECORD
            a:INTEGER;
         END;
   ras=RECORD(bas)
         b:REAL;
         END;
VAR
   c:bas;
   d:ras;
PROCEDURE Test (VAR x:bas);
BEGIN
   IF x IS ras THEN
                     Log.String("Расширенный тип");
                     Log.Ln;
   ELSE
            Log.String("Базовый тип");
            Log.Ln;
   END;
END Test;
BEGIN
   Test(c);
   Test(d);
END TestExt.


Я скорее думаю, что реализация оператора IS (и оператора WITH) не подразумевает прямое использование разыменованного указателя (динамического типа) как статического типа записи, поэтому требуется отдельная процедура, где разыменованный указатель (с помощью идентификатора VAR или IN) приводится к статическому типу записи. Вот цитата из книги Раизера и Вирта (в гуглопереводе):

Правило типа для параметров VAR смягчено: тип фактических параметров может быть расширением типа формального параметра VAR.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проверка типов оператором IS
СообщениеДобавлено: Вторник, 13 Сентябрь, 2022 17:40 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1354
Откуда: Киев
Цитата:
По поводу бессмысленных проверок с заранее известным результатом - можно ли вот такой пример считать примером бессмысленных проверок:
Нельзя. Компилятор использует лишь простые проверки осмысленности, и закладывать в языке общего назначения большее - это глупость, потому что приведёт к более сложной минимальной реализации. В совокупности с другими схожими требованиями это может осложнить задачу на один-два порядка в зависимости от аппетита. Это уже задача для опционального анализатора. И это то, как реализация влияет на дизайн.

Цитата:
Я скорее думаю, что реализация оператора IS (и оператора WITH) не подразумевает прямое использование разыменованного указателя (динамического типа) как статического типа записи, поэтому требуется отдельная процедура, где разыменованный указатель (с помощью идентификатора VAR или IN) приводится к статическому типу записи
Вы изначально спросили о причине ограничения, а здесь уже сами в качестве причины указали само ограничение. Технически здесь нет никаких сложностей, так как наличие процедуры ничего не упрощает, и здесь как раз дизайн влияет на реализацию.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проверка типов оператором IS
СообщениеДобавлено: Вторник, 13 Сентябрь, 2022 17:56 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 17
Comdiv писал(а):
Цитата:
По поводу бессмысленных проверок с заранее известным результатом - можно ли вот такой пример считать примером бессмысленных проверок:
Нельзя. Компилятор использует лишь простые проверки осмысленности, и закладывать в языке общего назначения большее - это глупость, потому что приведёт к более сложной минимальной реализации. В совокупности с другими схожими требованиями это может осложнить задачу на один-два порядка в зависимости от аппетита. Это уже задача для опционального анализатора. И это то, как реализация влияет на дизайн.

Цитата:
Я скорее думаю, что реализация оператора IS (и оператора WITH) не подразумевает прямое использование разыменованного указателя (динамического типа) как статического типа записи, поэтому требуется отдельная процедура, где разыменованный указатель (с помощью идентификатора VAR или IN) приводится к статическому типу записи
Вы изначально спросили о причине ограничения, а здесь уже сами в качестве причины указали само ограничение. Технически здесь нет никаких сложностей, так как наличие процедуры ничего не упрощает, и здесь как раз дизайн влияет на реализацию.


Я заранее извиняюсь, поскольку не программист по образованию, поэтому могу некорректно употреблять термины. И мы, видимо, не совсем понимаем друг друга. Вот код:
Код:
MODULE TestExt;
IMPORT Log;
TYPE
   pbas=POINTER TO bas;
   bas=EXTENSIBLE RECORD
            a:INTEGER;
            END;
   pras=POINTER TO ras;
   ras=RECORD (bas)
            b:REAL;
            END;
VAR
   c:pbas;
   d:pras;
PROCEDURE Test(VAR x:bas);
BEGIN
   IF x IS ras THEN
                     Log.String('Расширенный тип');
                     Log.Ln;
   ELSE
            Log.String('Базовый тип');
            Log.Ln;
   END;
END Test;
BEGIN
   NEW(c);
   NEW(d);
   Test(c^);
   Test(d^);
END TestExt.


Он корректно работает. Мой вопрос такой - почему через процедуру сравнить разыменованный указатель с типом записи можно, а напрямую, в теле модуля, нельзя?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проверка типов оператором IS
СообщениеДобавлено: Вторник, 13 Сентябрь, 2022 18:17 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1354
Откуда: Киев
Я уже ответил - это побочный эффект запрета тривиально выявляемых бессмысленных проверок и некритичный, элементарно обходимый, недочёт дизайна языка. Возможно, Вам нужно объяснение этого же другими словами? Задавайте уточняющие вопросы, но, пожалуйста, не ходите по кругу.

1. Можете сказать, зачем Вам нужна проверка типа записи у разыменованного указателя вместо проверки непосредственно указателя?

И вернёмся к примеру.
2. Понимаете, почему в процедуре проверка типа записи VAR-параметра осмысленна, так как фактический тип параметра в вызванной процедуре неизвестен?
3. Понимаете, почему проверка типа записи непосредственно объявленной переменной бессмысленна, так как её тип в момент проверки известен?


Последний раз редактировалось Comdiv Вторник, 13 Сентябрь, 2022 20:10, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проверка типов оператором IS
СообщениеДобавлено: Вторник, 13 Сентябрь, 2022 20:10 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 17
Просто когда я стал изучать расширение записи, меня заинтересовала данная ошибка компиляции. Ваш ответ меня убедил, благодарю Вас.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проверка типов оператором IS
СообщениеДобавлено: Среда, 14 Сентябрь, 2022 21:59 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 17
Comdiv писал(а):
Я уже ответил - это побочный эффект запрета тривиально выявляемых бессмысленных проверок и некритичный, элементарно обходимый, недочёт дизайна языка. Возможно, Вам нужно объяснение этого же другими словами? Задавайте уточняющие вопросы, но, пожалуйста, не ходите по кругу.

1. Можете сказать, зачем Вам нужна проверка типа записи у разыменованного указателя вместо проверки непосредственно указателя?

И вернёмся к примеру.
2. Понимаете, почему в процедуре проверка типа записи VAR-параметра осмысленна, так как фактический тип параметра в вызванной процедуре неизвестен?
3. Понимаете, почему проверка типа записи непосредственно объявленной переменной бессмысленна, так как её тип в момент проверки известен?


Я Ваш ответ для себя интерпретировал следующим образом:
1. Разыменованный типовой указатель подобен статической записи, поэтому сравнение одной статической записи с другой бессмысленно.
2. Идентификаторы VAR и IN в процедурах описывают параметры-переменные, которые поэтому могут считаться динамическими типами.
3. Указатели считаются динамическими типами, поэтому проверка типов может осуществляться как в процедуре, так и в теле модуля.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проверка типов оператором IS
СообщениеДобавлено: Среда, 14 Сентябрь, 2022 22:26 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1354
Откуда: Киев
1. Разыменованный указатель не подобен статической записи, так как точный тип структуры разыменованного указателя в общем случае неизвестен статически и здесь, действительно, можно было бы проверять тип, но эта проверка легко заменяется на проверку указателя без его разыменования и это по сути ничего не меняет. Большинство людей никогда не встречается с необходимостью проверки типа разыменованного указателя, а не его самого. То есть, смысл есть, но насущной потребности нет.
2. Параметры-переменные для записей по своим свойствам частично подобны указателям на записи.
3. В КП указатели и VAR и IN-параметры и только они позволяют ссылаться как на непосредственно тот тип записи, что был указан в объявлении, так и на номинально расширенные от него записи, поэтому в этих и только в этих случаях проверка имеет смысл.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проверка типов оператором IS
СообщениеДобавлено: Четверг, 15 Сентябрь, 2022 07:17 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 17
Comdiv писал(а):
1. Разыменованный указатель не подобен статической записи, так как точный тип структуры разыменованного указателя в общем случае неизвестен статически и здесь, действительно, можно было бы проверять тип, но эта проверка легко заменяется на проверку указателя без его разыменования и это по сути ничего не меняет. Большинство людей никогда не встречается с необходимостью проверки типа разыменованного указателя, а не его самого. То есть, смысл есть, но насущной потребности нет.
2. Параметры-переменные для записей по своим свойствам частично подобны указателям на записи.
3. В КП указатели и VAR и IN-параметры и только они позволяют ссылаться как на непосредственно тот тип записи, что был указан в объявлении, так и на номинально расширенные от него записи, поэтому в этих и только в этих случаях проверка имеет смысл.

Благодарю вас за подробные ответы.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проверка типов оператором IS
СообщениеДобавлено: Пятница, 16 Сентябрь, 2022 07:27 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 17
Comdiv писал(а):
1. Разыменованный указатель не подобен статической записи, так как точный тип структуры разыменованного указателя в общем случае неизвестен статически и здесь, действительно, можно было бы проверять тип, но эта проверка легко заменяется на проверку указателя без его разыменования и это по сути ничего не меняет. Большинство людей никогда не встречается с необходимостью проверки типа разыменованного указателя, а не его самого. То есть, смысл есть, но насущной потребности нет.
2. Параметры-переменные для записей по своим свойствам частично подобны указателям на записи.
3. В КП указатели и VAR и IN-параметры и только они позволяют ссылаться как на непосредственно тот тип записи, что был указан в объявлении, так и на номинально расширенные от него записи, поэтому в этих и только в этих случаях проверка имеет смысл.


И я бы хотел прояснить отличия в операторах IS и WITH. Насколько я понял, результатом оператора p IS T будет то, что p является типом T или его расширениями, поэтому доступ к полям осуществляется в виде p(T).имя поля, а результатом оператора WITH p:T будет то, что p строго соответствует типу T и доступ к полям осуществляется обычной записью p.имя поля?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проверка типов оператором IS
СообщениеДобавлено: Пятница, 16 Сентябрь, 2022 07:59 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3253
Нет, результат проверки одинаковый. IS также сработает и для предка. Однако IS не может трактовать, что потом будет с этой записью делаться, поэтому и тип автоматически не кастует для дальнейшего кода. Вы можете проверить тип, а потом запись использовать как угодно или вообще не использовать. А вот WITH предопределяет дальнейшее использование записи в своём теле однозначно, именно как наследника определённого типа.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проверка типов оператором IS
СообщениеДобавлено: Пятница, 16 Сентябрь, 2022 09:37 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 17
Иван Денисов писал(а):
Нет, результат проверки одинаковый. IS также сработает и для предка. Однако IS не может трактовать, что потом будет с этой записью делаться, поэтому и тип автоматически не кастует для дальнейшего кода. Вы можете проверить тип, а потом запись использовать как угодно или вообще не использовать. А вот WITH предопределяет дальнейшее использование записи в своём теле однозначно, именно как наследника определённого типа.


Я имел в виду, что IS рассматривает указанный объект p как динамический, который на момент проверки имеет тип T, поэтому и обращается к нему как p(T), а WITH рассматривает объект p как статический типа T, поэтому обращается к нему просто как p.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проверка типов оператором IS
СообщениеДобавлено: Пятница, 16 Сентябрь, 2022 22:38 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1354
Откуда: Киев
Вы очень странно интерпретируете правила языка. Рассматривайте язык как простейшую машину, которая способна выполнять код согласно описанию языка. Это, кстати, правда - язык программирования - это абстракция вычислительной машины.

Конкретно WITH можно конструктивно выразить через IS и var(Type), ровно как и наоборот. Не стоит искать сложные интерпретации в духе того, как это может делать человек. Конструкцию языка ничего не рассматривают.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проверка типов оператором IS
СообщениеДобавлено: Пятница, 16 Сентябрь, 2022 23:04 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 17
Comdiv писал(а):
Вы очень странно интерпретируете правила языка. Рассматривайте язык как простейшую машину, которая способна выполнять код согласно описанию языка. Это, кстати, правда - язык программирования - это абстракция вычислительной машины.

Конкретно WITH можно конструктивно выразить через IS и var(Type), ровно как и наоборот. Не стоит искать сложные интерпретации в духе того, как это может делать человек. Конструкцию языка ничего не рассматривают.


Благодарю вас за разъяснения.


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

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


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

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


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

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