Оберон-клуб «ВЄДАsoft»

Твердыня модульных языков
Текущее время: 28 мар 2024, 23:56

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




Начать новую тему Ответить на тему  [ Сообщений: 33 ]  На страницу Пред.  1, 2, 3, 4  След.
Автор Сообщение
 Заголовок сообщения: Re: FOR в Обероне 7. Стало только хуже
СообщениеДобавлено: 07 июн 2019, 12:55 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Comdiv писал(а):
Saferoll писал(а):
Теперь давайте посчитаем, сколько раз был нужен "правильный FOR". Разве Вам самому не интересно?
Посчитайте, например, здесь. Насколько, я понял там проводились какие-то вычисления для каждого байта. Естественно, был использован цикл FOR по всему диапазону. Но этот FOR по непонятной причине зациклился (хотя аналогичный FOR, например, в Паскале не зацикливается даже на всем диапазоне).
Само собой, можно использовать тип большей разрядности, можно крайние значения обрабатывать отдельно, можно еще как-то проблему решить. Но не лучше ли использовать другой FOR, где такой проблемы нет, поэтому и решать ее не придется.

_________________
А кроме того, я думаю, что корFORген должен быть разрушен!


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: FOR в Обероне 7. Стало только хуже
СообщениеДобавлено: 07 июн 2019, 13:45 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Ответ Comdiv про неопределенное поведение, перехват ошибок и обработку особых случаев на краю диапазона.
Можно называть необычное поведение цикла FOR на границе диапазона как угодно - ошибка, неопределенное поведение, особенность, дефект, фича. Но разве не следует признать, что это плохо, как бы не называлось? В руководстве указано, что тело цикла выполняется для всех значений переменных в указанном отрезке и перед каждой итерацией переменной присваивается очередное значение из этого отрезка. Значит, логично предположить, что для задания отрезка допустимо любое значение, которое можно этой переменной присвоить. В том числе и края диапазона типов, ведь их же тоже присвоить можно. Т.е.
Код: "OBERON"
  1. FOR b:=-128 TO 127 DO ...
должен сработать для всех байтов. В Турбопаскале, Дельфи, FPC работает же!
Но нет! Стандартный FOR в Обероне имеет дефект на границе типа. Почему такой дефект? Потому что неправильно реализован переход к следующему значению. Этот переход сначала совершается, а потом проверяется не выскочили ли за пределы. Поэтому такой цикл правильно работает только тогда, когда за последним значение есть буфер (ничейная земля, пространство для маневра), иначе - авария. Поэтому и не срабатывает на границе типа - за границей буфера нет.
Это ошибочная реализация, потому что цикл должен выполнить итерации только от А до В, от сих до сих, только в указанных пределах. А он лезет за пределы. Зачем? Затем что так легче всего проверить выход. Но почему бы не использовать другой метод проверки, чтобы такого выхода не было. И тогда получим цикл FOR без этой особенности. Реализовать это конечно сложнее, но вполне можно. Причем усложняется только компилятор, а сам цикл может быть очень эффективным (даже лучше чем стандартный).
Так зачем держаться за дефект? Зачем писать оговорки, дополнительные проверки, обработку особых случаев для граничных значений, если можно легко обойтись без этого? Тем более, что для внутренних значений цикл выполняется точно также. Разница на границе типа: стандартный FOR зациклится или вылетит с ошибкой, корректный - выполнит тело цикла для граничного значения и остановится. А если были написаны какие-то проверки и особые обработки, то они сработают одинаково для обоих видов цикла.

_________________
А кроме того, я думаю, что корFORген должен быть разрушен!


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: FOR в Обероне 7. Стало только хуже
СообщениеДобавлено: 07 июн 2019, 13:49 
Не в сети

Сообщения: 146
Saferoll писал(а):
Посчитайте, например, здесь.

Не 1-н же раз?
Да и под "правильный FOR" этот случай не подходит. Как я уже писал, поведение без зависания допускается и для текущего описания, если соответствующим образом воплотить целочисленное переполнение, тоже являющемся неопределённым поведением в описании.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: FOR в Обероне 7. Стало только хуже
СообщениеДобавлено: 07 июн 2019, 13:54 
Не в сети

Сообщения: 146
Saferoll писал(а):
Но нет! Стандартный FOR в Обероне имеет дефект на границе типа.
Я всё пытаюсь донести ту мысль, что неточность описания такова, что она в том числе допускает поведение FOR без зависания и поэтому допустимо так воплотить. То есть проблема в указанном примере не в том, что FOR неправильный, а в том, что описание недостаточно хорошо разжёвано, что обычное дело для авторских текстов. Чтобы сделать более точное описание, при этом не противоречащее авторскому, нужна работа коллектива.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: FOR в Обероне 7. Стало только хуже
СообщениеДобавлено: 07 июн 2019, 14:04 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Comdiv писал(а):
Как я уже писал, поведение без зависания допускается и для текущего описания, если соответствующим образом воплотить целочисленное переполнение, тоже являющемся неопределённым поведением в описании....
Я всё пытаюсь донести ту мысль, что неточность описания такова, что она в том числе допускает поведение FOR без зависания и поэтому допустимо так воплотить. То есть проблема в указанном примере не в том, что FOR неправильный, а в том, что описание недостаточно хорошо разжёвано, что обычное дело для авторских текстов. Чтобы сделать более точное описание, при этом не противоречащее авторскому, нужна работа коллектива.
Пожалуйста, укажите, как можно толковать переполнение, чтобы цикл FOR корректно завершался на границе диапазона.

_________________
А кроме того, я думаю, что корFORген должен быть разрушен!


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: FOR в Обероне 7. Стало только хуже
СообщениеДобавлено: 07 июн 2019, 14:09 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Comdiv писал(а):
Не 1-н же раз?
Да и под "правильный FOR" этот случай не подходит.
Почему же не подходит? Ведь если написан такой цикл, значит автор рассчитывал, что FOR поведет себя "как правильный", т.е. для верного выполнения его программы, ему был нужен правильный FOR. А когда обнаружилось зацикливание, то это вызвало удивление. И не только у топикстартера, значит они тоже написали бы такую же программы в этом случае - их тоже можно сосчитать. И посмотрите как люди разбирались в чем дело, а это ведь не новички в программировании. Значит, такая особенность стандартного FOR не очевидна из документации.

_________________
А кроме того, я думаю, что корFORген должен быть разрушен!


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: FOR в Обероне 7. Стало только хуже
СообщениеДобавлено: 07 июн 2019, 14:49 
Не в сети

Сообщения: 146
Saferoll писал(а):
Почему же не подходит?
Потому что ему не нужны все перечисленные особенности "правильного FOR", а для реализации без зависания подходит и обычное описание. Проблема описания не в том, что оно запрещает независающий вариант, а в том, что не запрещает зависающий. Но допустимо воплотить независающий, к чему я и призываю.

Цитата:
Пожалуйста, укажите, как можно толковать переполнение, чтобы цикл FOR корректно завершался на границе диапазона.
Например, так
Код: "OBERON"
  1. #include <limits.h>
  2. #include <stdio.h>
  3. #include <stdbool.h>
  4.  
  5. typedef struct {
  6. char signed val;
  7. bool undef;
  8. } BYTE;
  9.  
  10. bool LE(BYTE l, BYTE r) {
  11. return !l.undef && !r.undef
  12. && l.val <= r.val;
  13. }
  14.  
  15. void INC(BYTE *b) {
  16. if (b->val >= SCHAR_MAX) {
  17. b->undef = true;
  18. } else {
  19. b->val += 1;
  20. }
  21. }
  22.  
  23. int main(void) {
  24. BYTE b;
  25. /*
  26. FOR b := MIN(BYTE) TO MAX(BYTE) DO
  27. Out.Int(b, 0); Out.Ln
  28. END;
  29.  
  30. b := MIN(BYTE);
  31. WHILE b <= MAX(BYTE) DO
  32. Out.Int(b, 0); Out.Ln;
  33. INC(b)
  34. END
  35. */
  36. b = (BYTE){SCHAR_MIN, false};
  37. while (LE(b, (BYTE){SCHAR_MAX, false})) {
  38. printf("%d\n", b.val);
  39. INC(&b);
  40. }
  41. }
  42.  

Такие трактовки могут быть чисто умозрительными и для того же FOR можно просто воплотить желаемое поведение, наподобие того, что уже воплощено Вами.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: FOR в Обероне 7. Стало только хуже
СообщениеДобавлено: 08 июн 2019, 19:31 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Comdiv писал(а):
Цитата:
Пожалуйста, укажите, как можно толковать переполнение, чтобы цикл FOR корректно завершался на границе диапазона.
Например, так
...
Такие трактовки могут быть чисто умозрительными и для того же FOR можно просто воплотить желаемое поведение, наподобие того, что уже воплощено Вами.

Спасибо, я вот не додумался, что неопределенность переполнения можно так истолковать. Т.е. можно сделать FOR, который не зацикливается и сказать "это стандартный FOR, только переполнение у нас специфическое". Получается, что переполнение дает некое особое значение, отличное от остальных чисел. И это особое значение больше любого числа в сравнении <=, но меньше любого в сравнении >=. Т.е. нужно расширить множество значений целых чисел, добавив туда какое-то особое значение. Хотя, например, при трансляции в JS это не столь и обременительно.
Можно также, например, принять такую трактовку "если переполнение в инкременте или декременте, который завершает тело цикла WHILE, то этот цикл завершается". Тогда тоже FOR бы не зациклился.
Но в любом случае ситуация "может при определенной трактовке выполниться правильно даже на краю диапазона" хуже чем "всегда выполняется правильно для всех значений". Лучше уж не трактовать возникшее переполнение, а просто возникновения не допускать, ведь переполнение - это какая-то аварийная особая ситуация. И, в отличии от деления на 0, тут можно легко ее избежать.
Ведь почему произошло переполнение? Потому что выполнился инкремент (ну или декремент). Но инкремент при выполнении FOR не самоцель, он нужен для получения следующего значения в последовательности чисел. А когда тело цикла выполнилось в последний раз, следующее значение не нужно, ведь цикл должен обработать только те значения, что содержатся в диапазоне. А раз не нужно значение, то не нужен и инкремент! Ведь этот инкремент может вызвать переполнение, которого лучше избежать, чем перехватывать потом изощренной трактовкой.
Почему же инкремент выполняется? Потому что он прописан в стандарте - там жестко прописан неправильный механизм перебора значений, механизм с лишним инкрементом.
Вот в чем причина, а не в трактовке неопределенности. Поэтому, чем выискивать такую трактовку, которая позволяет даже столь дефектному стандарту исполниться правильно, лучше признать сразу, что стандарт дефектный и заменить другим. Таким, который без всяких трактовок верно выполняется. И не прописывать конкретный механизм, пусть это выбирает компилятор, в зависимости от константности параметров и величины самих параметров. В теме "Модификация Ofront. Реализуем "правильный" FOR" я рассмотрел несколько таких случаев, получается довольно эффективно даже на уровне С (еще более эффективный код получился бы с учетом команд конкретного процессора). Расплата за это - усложненный компилятор, но даже самый простой механизм реализации незацикливающего FOR лучше, чем стандарт с переполнением.

_________________
А кроме того, я думаю, что корFORген должен быть разрушен!


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: FOR в Обероне 7. Стало только хуже
СообщениеДобавлено: 08 июн 2019, 19:47 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Zorko сообщил мне, что он со товарищи (за что ему и им всем спасибо!) заглянул в виртовский компилятор http://www.projectoberon.com/ , чтобы разобраться в трактовке FOR самого автора.
Вот этот фрагмент отвечает за реализацию FOR
Код: "OBERON"
  1. ELSIF sym = ORS.for THEN
  2. ORS.Get(sym);
  3. IF sym = ORS.ident THEN
  4. qualident(obj); ORG.MakeItem(x, obj, level); CheckInt(x); CheckReadOnly(x);
  5. IF sym = ORS.becomes THEN
  6. ORS.Get(sym); expression(y); CheckInt(y); ORG.For0(x, y); L0 := ORG.Here();
  7. Check(ORS.to, "no TO"); expression(z); CheckInt(z); obj.rdo := TRUE;
  8. IF sym = ORS.by THEN ORS.Get(sym); expression(w); CheckConst(w); CheckInt(w)
  9. ELSE ORG.MakeConstItem(w, ORB.intType, 1)
  10. END ;
  11. Check(ORS.do, "no DO"); ORG.For1(x, y, z, w, L1);
  12. StatSequence; Check(ORS.end, "no END");
  13. ORG.For2(x, y, w); ORG.BJump(L0); ORG.FixLink(L1); obj.rdo := FALSE
  14. ELSE ORS.Mark(":= expected")
  15. END
  16. ELSE ORS.Mark("identifier expected")
  17. END
  18. ELSIF
Хотя компилятор у Вирта, конечно, другой, но в чем-то сходство с Ofront имеется. Вполне достаточное сходство, чтобы понять, что никакой временной переменной и не пахнет, а тело цикла FOR подставляется в WHILE без проверки, что это одиночный вызов процедуры без параметров.
Так что FOR просто превращается в тот самый эквивалентный WHILE-фрагмент с перевычислением граничного выражения перед каждой итерацией, как и указано в описании.

_________________
А кроме того, я думаю, что корFORген должен быть разрушен!


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: FOR в Обероне 7. Стало только хуже
СообщениеДобавлено: 09 июн 2019, 18:27 
Не в сети

Сообщения: 146
Saferoll писал(а):
Но в любом случае ситуация "может при определенной трактовке выполниться правильно даже на краю диапазона" хуже чем "всегда выполняется правильно для всех значений".
Я ответил на Ваш вопрос о том, как можно трактовать переполнение, чтобы FOR завершился правильно в Вашем понимании, но не на вопрос, как лучше всего трактовать переполнение в рамках O7. А ответ на этот вопрос - как ошибку с диагностикой. Если Вы хотите обеспечить совместимость с O7(языком, а не конкректной реализацией), не давая лишних ожиданий, то лучше сделать именно так. Тем более, что в O7 по описанию предусмотрен лишь INTEGER итератор, а его переполнить в FOR сложней. Кстати, как ошибку лучше трактовать абсолютно все переполнения, а не только в FOR.

Цитата:
дефектному стандарту
Нет никакого стандарта, есть лишь краткое авторское описание и нет ничего удивительного, что оно достаточно размыто. Об этом я тоже уже писал неоднократно в разных местах - для создания стандарта нужно объединиться группе заинтересованных лиц и совместными усилиями создать понятное многим, непротиворечивое и более точное описание. Правда, это близко к невозможному, учитывая уровень дискуссий.
В любом случае, описанный Вами "правильный FOR" не подходит для стандарта Oberon, так как стандарт, скорее, нужен для повышения точности описания языка, а не для смены семантики его конструкций, то есть изменению самого языка. В этом плане показательна работа ANSI по стандартизации языка Си.
И важно уточнить - в этой теме я всё время веду речь о режиме совместимости с O7. В конце-концов, посмотрите, как Вы назвали тему. Как делать в других диалектах - это совершенно другой вопрос, и как я уже писал, там можно всё сделать радикально.


Вернуться к началу
 Профиль  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 33 ]  На страницу Пред.  1, 2, 3, 4  След.

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


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

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


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

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
© VEDAsoft Oberon Club