Коллеги, вот такой пример демонстрирует, что IS иногда определен для неопределенных переменных, а иногда - нет:
## Код:
```
TYPE
      Base = POINTER TO EXTENSIBLE RECORD END;
      Ext = POINTER TO RECORD (Base) END;

   PROCEDURE P*;
      VAR e: Ext; b: Base;
   BEGIN 
      IF e IS Ext THEN Log.String("(e = NIL) & (e IS Ext)"); Log.Ln END;
      (*1*)IF b IS Ext THEN Log.String("unreachable"); Log.Ln END
   END P;
```


Эта программа вычисляет e IS Ext = TRUE, выводит сообщение в журнал, и затем аварийно останавливается в (*1*).
Для меня было неожиданно, что e IS Ext определено при e = NIL, я ожидал авост. В сообщении о языке сказано:
> -- Цитата:
> 8.2.5 Relationsv IS T stands for "the dynamic type of v is T (or an extension of T)" and is called a type test. It is applicable if1.  v is an IN or VAR parameter of record type or v is a pointer to a record type, and if2.  T is an extension of the static type of v.....Appendix AA type Tb is an extension of a type Ta (Ta is a base type of Tb) if1.  Ta and Tb are the same types
Т.е. как я понимаю, случай v = NIL не оговаривается; остается только домысливать, что поскольку v = NIL, то ее фактический тип (динамический) не определен, и потому IS также не определен.

Но в моем примере формальный тип (статический) переменной е - концевой, поэтому любое значение, кроме NIL - типа Ext; вероятно, поэтому компилятор "оптимизирует" и вместо вычисления сразу вставляет ИСТИНУ.

Мне кажется, что правильнее было бы проверку e IS Ext не заменять на инвариантную ИСТИНУ, а отказываться компилировать. Поскольку в приведенном примере она бессмысленна, ее присутствие в тексте - вероятно, следствие того, что Ext ранее был расширяемым типом, а потом, при редактировании программы, стал концевым. А процедура P не была должным образом поправлена, и бывшая осмысленной проверка типа стала бессмысленной. Отказавшись это компилировать, компилятор помог бы выявить потенциальную ошибку в логике программы.

Что скажете?