OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Воскресенье, 09 Август, 2020 21:02

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




Начать новую тему Ответить на тему  [ Сообщений: 19 ] 
Автор Сообщение
 Заголовок сообщения: Суровый баг в XDS Oberon
СообщениеДобавлено: Среда, 09 Апрель, 2008 23:27 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2349
Откуда: Россия, Томск
Нашёл сегодня при написании тестового приложения. Заодно опишу задачу, может быть кто-то посоветует более элегантное решение.

Пусть у нас есть тип 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-параметра в первом примере и возвращения результата процедуры во втором (т.е. исключить необходимость изменения корня списка).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Четверг, 10 Апрель, 2008 00:45 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Александр Ильин писал(а):
Нашёл сегодня при написании тестового приложения. Заодно опишу задачу, может быть кто-то посоветует более элегантное решение.


Отделите тип "список" от типа "элемент списка". Все сразу станет понятнее и обобщеннее.

P.S. Предлагаю оберонщикам, перед тем как начать захватывать мир, завести хоть сколько-нибудь стандартную библиотеку контейнеров. Хотя бы уровня упоминавшейся здесь когда-то "ГРОМ"'. Это ж детский сад - для каждой задачи городить еще один более удобный и красивый список...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Четверг, 10 Апрель, 2008 03:12 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8351
Откуда: Троицк, Москва
Vlad писал(а):
P.S. Предлагаю оберонщикам, перед тем как начать захватывать мир, завести хоть сколько-нибудь стандартную библиотеку контейнеров. Хотя бы уровня упоминавшейся здесь когда-то "ГРОМ"'. Это ж детский сад ...


Детский сад -- не понимать своего непонимания.
Тоже мне, "уровень".

Это напоминает плодящиеся системы компьютерной алгебры на С++, в которых есть "всё", и которыми невозможно пользоваться.

За 15 лет лично у меня не появилось необходимости в "стандартной библиотеке".
Для конкретных классов подзадач -- да. Но там, как правило, всё сделать легко, и никакой необходимости в очередном универсальном монстре не просматривается.

Скрывать всё вообразимое разнообразие опцый за каким-то монструозным интерфейсом, который прикрывает поле next -- глупость.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Четверг, 10 Апрель, 2008 08:07 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2349
Откуда: Россия, Томск
Vlad писал(а):
Отделите тип "список" от типа "элемент списка". Все сразу станет понятнее и обобщеннее.

Спасибо, подумаю.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Четверг, 10 Апрель, 2008 11:33 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4593
Откуда: Россия, Орёл
Vlad писал(а):
Отделите тип "список" от типа "элемент списка". Все сразу станет понятнее и обобщеннее.

Понятнее? "На вкус и цвет товарища нет" :) Я бы еще подумал - выносить голову списка в отдельный тип или хранить её в элементе списка, затрачивая на каждый список лишний ARRAY 64 OF CHAR. Как раз чтобы не иметь дела с двумя типами. При этом вся обработка упрощается, т.к. у любого элемента есть предыдущий и не надо писать IF list = NIL

Такой подход наиболее удобен, если список сначала строится а потом используется. Сначала делаем голову, чтобы не писать IF list = NIL ... После построения её отрубаем list := list.next и возвращаем безголовый список :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Четверг, 10 Апрель, 2008 15:10 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2349
Откуда: Россия, Томск
Евгений Темиргалеев писал(а):
После построения её отрубаем list := list.next и возвращаем безголовый список :)
Евгений, присуждаю вам приз "5 баллов" за отличную подсказку! Это именно то, что нужно в моём случае : )


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Четверг, 10 Апрель, 2008 15:13 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Поле next имеет тип Item, значит и переменная list тоже должна иметь тип Item, а не ItemExt.

Ведь для того чтобы пробежаться по списку всё-равно нужно будет делать приведение типа -- так почему же для головы списка сделано особое отдельное исключение?

Объявляем list как просто Item:
Код:
VAR list: Item;
  new1: ItemExt1;
  new2: ItemExt2;
...
Add(list, new1);
Add(list, new2);

и приведения типов в процедуре Add делать не надо.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Четверг, 10 Апрель, 2008 19:24 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Info21 писал(а):
За 15 лет лично у меня не появилось необходимости в "стандартной библиотеке".


Это только лишний раз доказывает, что к программированию вы имеете такое же отношение, какое я к физике. Если бы вам приходилось читать чужой код на порядок чаще, чем колбасить свой, то у вас было бы другое отношение к стандартизации.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Четверг, 10 Апрель, 2008 19:44 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Евгений Темиргалеев писал(а):
Vlad писал(а):
Отделите тип "список" от типа "элемент списка". Все сразу станет понятнее и обобщеннее.

Понятнее? "На вкус и цвет товарища нет" :)


Понятнее и обобщеннее. Список - это структура, ввод соответствующего типа выражает это явно в коде. И это позволит написать функцию работы со списком один раз. Структура с полем "next" - это фиг знает что такое. Это может быть списком, а может и нет.

Евгений Темиргалеев писал(а):
Такой подход наиболее удобен, если список сначала строится а потом используется. Сначала делаем голову, чтобы не писать IF list = NIL ... После построения её отрубаем list := list.next и возвращаем безголовый список :)


Похоже у нас несовместимые понятия "удобства" и "наглядности".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Пятница, 11 Апрель, 2008 00:24 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2349
Откуда: Россия, Томск
Сергей Губанов писал(а):
... и приведения типов в процедуре Add делать не надо.
Просто нужно было получить список, корень которого имеет тип ItemExt. Вы правы, можно сделать переменную типа Item в качестве временного корня, а потом присвоить её значение в нужную переменную, применив охрану типа один раз.

Решение с подставным корнем укоротило процедуру Add почти вдвое: не надо обрабатывать особый случай (list = NIL), всё делается одним циклом без особых случаев.

При отрубании головы списка хотел использовать такой код:
Код:
list := list.next
Компилятор ругается, что list имеет тип ItemExt, а list.next - просто Item. Поставил охрану:
Код:
list := list.next (ItemExt)
После этого неоднократно столкнулся с ошибкой времени выполнения при охране типа в случае, когда list.next = NIL. Пришлось писать так:
Код:
IF list.next # NIL THEN list := list.next (ItemExt) END

Где-то здесь обсуждалось недавно, какой тип имеет NIL. Судя по данному случаю, NIL мог бы быть любого типа, присвоение ведь возможно. Мне кажется, охрана NIL не должна бы давать ошибку, результат охраны ведь является совместимым с указанным типом. Вот если бы я к полям или методам обращался, тогда другое дело.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Пятница, 11 Апрель, 2008 00:31 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2349
Откуда: Россия, Томск
Vlad писал(а):
Понятнее и обобщеннее. Список - это структура, ввод соответствующего типа выражает это явно в коде. И это позволит написать функцию работы со списком один раз.
Я и так написал один раз.
Код:
PROCEDURE Add (list, i: Item);
(* Add new item i to the list. The list is sorted by name, ascending. The first item in the list is a fake root. *)
BEGIN
   ASSERT (i # NIL, 20);
   ASSERT (i.next = NIL, 21);
   ASSERT (i.name # '', 22);
   ASSERT (list # NIL, 23);
   ASSERT (list.name = '', 24);
   WHILE (list.next # NIL) & (i.name > list.next.name) DO
      list := list.next
   END;
   i.next := list.next;
   list.next := i
END Add;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Пятница, 11 Апрель, 2008 01:51 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Александр Ильин писал(а):
Я и так написал один раз.


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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Пятница, 11 Апрель, 2008 07:09 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2349
Откуда: Россия, Томск
Vlad писал(а):
Отделите тип "список" от типа "элемент списка".
Vlad писал(а):
То что вы написали работает только для Item и его наследников.
А если я разделю список (List) и элемент списка (Item), разве это будет работать не только для Item и его наследников?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Пятница, 11 Апрель, 2008 08:19 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8351
Откуда: Троицк, Москва
Vlad писал(а):
Это только лишний раз доказывает, что к программированию вы имеете такое же отношение, какое я к физике.

Вот видите, Vlad, какие клеветы Вы постоянно себе позволяете. Нежно называя себя "несогласным". А мои возражения на Ваши клеветы называя разными словами.

Всё-таки к программированию я имею гораздо большее отношение, чем Вы -- к физике.

1) Вы же не обероновские коды читаете в указанных количествах.
2) Прямую реализацию простого списка (кои составляют подавляющее большинство всех списков) даже с какой-то особенностью на Обероне прочесть проще, чем вспоминать опции какой-нибудь монструозной "универсальной" библиотеки.
3) Если библиотека содержит опции на все случаи жизни, то программеры сумеют наварить там каши ничуть не слабее, чем с одним полем next.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Пятница, 11 Апрель, 2008 10:29 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
Александр Ильин писал(а):
Где-то здесь обсуждалось недавно, какой тип имеет NIL. Судя по данному случаю, NIL мог бы быть любого типа, присвоение ведь возможно. Мне кажется, охрана NIL не должна бы давать ошибку, результат охраны ведь является совместимым с указанным типом. Вот если бы я к полям или методам обращался, тогда другое дело.

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Пятница, 11 Апрель, 2008 18:54 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2349
Откуда: Россия, Томск
Александр Ильин писал(а):
После этого неоднократно столкнулся с ошибкой времени выполнения при охране типа в случае, когда list.next = NIL. Пришлось писать так:
Код:
IF list.next # NIL THEN list := list.next (ItemExt) END
Проглядел ошибку. Правильный код отрубания головы списка даже ещё длиннее:
Код:
IF list.next # NIL THEN list := list.next (ItemExt) ELSE list := NIL END


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Пятница, 11 Апрель, 2008 18:56 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Александр Ильин писал(а):
А если я разделю список (List) и элемент списка (Item), разве это будет работать не только для Item и его наследников?


Если Item будет ANYREC, то будет работать для всего ;)

P.S. А вот чего делать в оригинальном обероне - я не знаю. Как описать работу с любым типом?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Пятница, 11 Апрель, 2008 19:32 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Info21 писал(а):
Vlad писал(а):
Это только лишний раз доказывает, что к программированию вы имеете такое же отношение, какое я к физике.

Вот видите, Vlad, какие клеветы Вы постоянно себе позволяете. Нежно называя себя "несогласным". А мои возражения на Ваши клеветы называя разными словами.


Какие именно слова вам показались обидными? По поводу вашей далекости от программирования? Это мое личное мнение, сложившееся на основе ваших высказываний (в том числе и в этой ветке).

Info21 писал(а):
Всё-таки к программированию я имею гораздо большее отношение, чем Вы -- к физике.


Хорошо, какое именно отношение вы имеете к программированию? Я еще ничего ценного в ваших статьях/высказываниях не почерпнул. Ничего кроме критики необеронов. Читая Илью Ермакова, несмотря на его не меньшую одержимость оберонами, можно расширить свое понимание в области программирования. Ваше отношение к программированию для меня, как стороннего наблюдателя, примерно такое: физик использует BB для решения своих задач. С тем же успехом я могу ставить некие "физические опыты" у себя на балконе и причислять себя к физике :)

Info21 писал(а):
1) Вы же не обероновские коды читаете в указанных количествах.


А это не важно. Это объективное свойство сопровождения программ, независящее от языка - их приходится читать (и к сожалению не только компилятору, о котором так пекутся оберонщики). Итак, сколько обероновского кода вы читаете? Или само понятие "сопровождение программ" вам чуждо?

Info21 писал(а):
2) Прямую реализацию простого списка (кои составляют подавляющее большинство всех списков) даже с какой-то особенностью на Обероне прочесть проще, чем вспоминать опции какой-нибудь монструозной "универсальной" библиотеки.


Я видел тексты BB. Не проще.

Info21 писал(а):
3) Если библиотека содержит опции на все случаи жизни, то программеры сумеют наварить там каши ничуть не слабее, чем с одним полем next.


"Хорошие" программеры сумеют написать более читабельный код. "Плохим" - и одно поле next не помешает написать нечто несопровождаемое.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Суровый баг в XDS Oberon
СообщениеДобавлено: Суббота, 12 Апрель, 2008 14:32 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8351
Откуда: Троицк, Москва
Vlad писал(а):
...

У меня тоже сложилось о Вас мнение на основании Ваших сообщений, оно довольно невысокое, и Вам это обидно настолько, что Вы не гнушаетесь клеветами, передергиванием и переходами на личность.

Но к троллингу у Вас природный талант, отдаю должное.


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

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


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

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


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

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