Нашёл сегодня при написании тестового приложения. Заодно опишу задачу, может быть кто-то посоветует более элегантное решение.

Пусть у нас есть тип Item и его наследник ItemExt:## Код:
```
TYPE
   Str: ARRAY 64 OF CHAR;
   Item = POINTER TO ItemDesc;
   ItemDesc = RECORD next: Item; name: Str END;
   ItemExt = POINTER TO RECORD (ItemDesc) field: INTEGER END;
```
Item'ы объединены в односвязанный список и поименованы. Важно, чтобы в списке элементы были отсортированы по имени. Помимо ItemExt есть много других наследников от Item, поэтому захотел я написать единую процедуру Add, которая будет добавлять новый элемент сразу в нужное место списка:## Код:
```
PROCEDURE Add (VAR list: Item; i: Item);
BEGIN
   IF list = NIL THEN
      list := i
   ELSE
      (* добавляем i в список list*)
   END
END Add;
```
Идея процедуры такова: подаём первым параметром переменную-корень списка. Если список пуст (корень = NIL), то инициализируем корень первым элементом i. В противном случае добавляем i в существующий список, возможно, изменяя корень - если нужно вставить i в самое начало. Далее я создал список типа ItemExt, но как только я попытался вызвать Add (list, new), то компилятор на меня заругался, поскольку в качестве list я хотел передать ему ItemExt, что не соответствует VAR-параметру типа Item (предок). В самом деле, мало ли что там процедура может присвоить. Пришлось переделать, возвращая новый корень в результате:## Код:
```
PROCEDURE Add (list, i: Item): Item;
BEGIN
   IF list = NIL THEN
      RETURN i
   ELSE
      (* добавляем i в список list*)
      RETURN list
   END
END Add;
```
Соответственно, на выходе возникла необходимость в охране типа:## Код:
```
VAR list, new: ItemExt;
...
   NEW (new); new.name := ...
   list := Add (list, new)(ItemExt);
```

И вот тут случилось самое интересное. Оказывается, чтобы применить охрану типа к результату процедуры, XDS по-тихомувызывает процедуру второй раз!Хорошо, что у меня в Add был ASSERT (i.next = NIL), а то поди долго бы искал, почему зацикливается проход по списку.

Получается, что надо мне писать теперь## Код:
```
tmp := Add (list, new); list := tmp(ItemExt);
```
а это уже совсем далеко от элегантности первого решения. Подскажите, если кто с подобными списками работал, как мне быть. Общая задача такова: каждый список содержит только объекты одного типа, просто не хочется дублировать для каждого типа процедуру Add. У меня вариант только один: всегда создавать неиспользуемый корень списка, чтобы исключить причину для использования VAR-параметра в первом примере и возвращения результата процедуры во втором (т.е. исключить необходимость изменения корня списка).