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

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

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




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

Сообщения: 273
Откуда: Россия
Zorko попросил реализовать цикл FOR для совместимости с версией Оберон-7. Что же, попытаюсь вспомнить старые навыки. Теоретически, это должно быть просто – чуть подправить стандартный FOR Оберона. Но мне "религия" (вера в Истинный и Всеправедный FOR ) :D не позволяет просто так реализовывать такую "ересь", без того, что предварительно не обругать и не "предать анафеме". Вот сейчас этим и займусь.

Первоначально в Обероне 7 FOR был такой же, как в Оберон-2 и КП. Но в последней версии Оберон 7синтаксис оператора FOR выглядит так:
Цитата:
ForStatement = FOR ident ":=" expression TO expression [BY ConstExpression] DO StatementSequence END
А семантика определяется как эквивалентность конструкции
Код: "OBERON"
  1. FOR v := beg TO end BY inc DO S END
программному фрагменту (для inc > 0)
Код: "OBERON"
  1. v := beg; WHILE v <= end DO S; v := v + inc END
Для inc < 0 фрагмент отличается знаком условия:
Код: "OBERON"
  1. v := beg; WHILE v >= end DO S; v := v + inc END
В предыдущих версиях Оберона цикл FOR определялся как
Код: "OBERON"
  1. v := beg; t:=end; WHILE v <= t DO S; v := v + inc END
или
Код: "OBERON"
  1. v := beg; t:=end; WHILE v >= t DO S; v := v + inc END
где t–временная переменная.
Как видим, FOR в Обероне-7 практически 1-в-1 повторяет цикл в Си
Код: "C"
for(v=beg;v<=end;v+=inc); for(v=beg;v>=end;v+=inc);
Зачем это было сделано?! Экономия на временной переменной, стремление еще больше упростить или обеспечить большее сходство с Си?
В любом случае, считаю это ухудшением и отступлением от «генеральной линии Oberon way».
Я с глубочайшем уважением отношусь к профессору Вирту и его коллегам, но такой FOR вызывает у меня только резкие негативные чувства.
Вообще, с этим оператором в Обероне творится что-то странное. Как пишут разные источники, создавая Оберон, Вирт не стал включать в него FOR, посчитав этот оператор цикла излишним. В Оберон-2 FOR все-таки был включен (вроде бы с большого неудовольствия Вирта, только по настоянию). Но включен-то не самый лучший вариант, лучше бы вообще никакого не было! Почему то вместо сокрытого механизма изменения переменной, как это было в Паскале и Модуле, в Оберон вошел явный процедурный цикл через while (близкий к Си). И вот теперь ,в Оберон 7, сделан еще один шаг к Си - исчезла временная переменная.

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


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

Сообщения: 273
Откуда: Россия
Кстати, в новой книге «Алгоритмы и структуры данных» 2016 года во многих программах используется оператор FOR, но он вообще отсутствует в приложении «В.Синтаксис Оберона». Причем не только в НФБН, но даже в списке ключевых слов (хотя, неиспользуемые в книге WITH и IS в приложении приведены).
В оригинале Algorithms and Data Structures точно также, так что это не погрешность переводчиков.
Я уже писал ранее в темах
Цикл FOR. Следовать ли стандарту?
Мы наш, мы новый FOR построим
Модификация Ofront. Реализуем "правильный" FOR
чем именно плох стандартный, подобный сишному, FOR в Обероне и какие выгоды сулит FOR, приближенный к Паскалю и Модуле. А новый FOR в Обероне 7, кроме дефекта на границе диапазона, кроме дурной семантики, провоцирующей на трюки с изменением переменной цикла и отслеживанием ее значения после завершения, дарует новую возможность - изменять выражение, определяющее конечное значение. Не говоря уже о том, что вычисление выражения end в начале каждой итерации весьма неэффективно.

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


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

Сообщения: 273
Откуда: Россия
По сообщениям с форума Oberoncore можно проследить, когда примерно поменялся FOR:
в Revision 1.10.2013 / 10.3.2014 используется временная переменная "lim := end;";
в более поздней Revision 1.10.2013 / 1.5.2016 выражение end подставляется прямо в условие WHILE.
Т.е. где-то между этими версиями реализация FOR без лишнего шума и огласки поменялась.

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


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

Сообщения: 146
Saferoll писал(а):
Как видим, FOR в Обероне-7 практически 1-в-1 повторяет цикл в Си
Вы то ли шутите, то ли преувеличиваете, то ли плохо знакомы с Си.
Попробуйте повторить это c FOR в Обероне:
Код: "OBERON"
  1. for (;;);
  2. for(int i = 1; i < N && i[a] != 0; i *= 2);
  3. for(float one; two < N; three++);
  4. for(r > 8.0; rand() * 0.5 != 17; i < 8.0) printf("что хочу, то ворочу\n");
  5. ... чуть ли не любой вариант по вкусу
  6.  


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

Сообщения: 273
Откуда: Россия
Comdiv писал(а):
Вы то ли шутите, то ли преувеличиваете, то ли плохо знакомы с Си.
Попробуйте повторить это c FOR в Обероне:
Благодарю за уточнение, я действительно преувеличил (вернее, неточно выразился). Конечно же, не всякий сишный цикл for можно выразить через FOR в Обероне (даже в Обероне-7). Более корректно было написать "Теперь цикл FOR в Оберон-7 стал еще ближе к циклу for в языке С."
Ведь теперь цикл
Код: "OBERON"
  1. FOR v := beg TO end BY inc DO S END

соответствует (в зависимости от знака inc) циклу С
Код: "C"
for(v=beg;v<=end;v+=inc){S}; 
for(v=beg;v>=end;v+=inc){S};


Рассмотрим 2 полюса - цикл FOR в Паскале/Модуле и цикл for в С. В Паскале изменение значения переменной цикла скрыто где-то внутри, нет зацикливания на границах диапазона, запрещено менять значение переменной цикла в теле цикла (если сменить, может получиться что угодно), по окончании цикла значение переменной цикла является неопределенным. Кроме того, изменение граничного выражения внутри цикла не влияет на количество итераций.
В языке С все условия и инкременты\декременты совершаются явно, for - просто иная запись для некоторого while. Поэтому возможны трюки с изменением значений переменной или граничного выражения, а также использование значения параметра цикла после окончания.
В Обероне-2, КП и ранних версиях Оберон-7 цикл FOR был где-то посередине (как в С, за исключением того, что граничное выражение вычислялось 1 раз перед циклом, поэтому изнутри цикла его нельзя было изменить). В Обероне 7 с Revision 1.10.2013 / 1.5.2016 (или чуть раньше) стало практически 1-в-1 как в С ("1-в-1" по побочным эффектам и трюкам, а не по возможностям втиснуть в цикл любые условия и операторы).

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


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

Сообщения: 273
Откуда: Россия
Что же до реализации такого цикла, то это просто. Нужно немного переделать стандартный цикл FOR Оберона-2. В модуле OfrontOPP чуть подправим процедуру:
Код: "OBERON"
  1. PROCEDURE ForOriginal;
  2. BEGIN
  3. OPS.Get(sym);
  4. IF sym = ident THEN qualident(id);
  5. IF ~(id^.typ^.form IN intSet) THEN err(68) END ;
  6. CheckSym(becomes); Expression(y); pos := OPM.errpos;
  7. x := OPB.NewLeaf(id); OPB.Assign(x, y); SetPos(x);
  8. CheckSym(to); Expression(y); pos := OPM.errpos;
  9. IF y^.class # Nconst THEN
  10. name := "@@"; OPT.Insert(name, t); t^.name := OPT.NewName("@for"); (* avoid err 1 *)
  11. t^.mode := Var; t^.typ := x^.left^.typ;
  12. obj := OPT.topScope^.scope;
  13. IF obj = NIL THEN OPT.topScope^.scope := t
  14. ELSE
  15. WHILE obj^.link # NIL DO obj := obj^.link END;
  16. obj^.link := t
  17. END;
  18. z := OPB.NewLeaf(t); OPB.Assign(z, y); SetPos(z); OPB.Link(stat, last, z);
  19. y := OPB.NewLeaf(t)
  20. ELSIF (y^.typ^.form IN {Undef, Bool, Char}) THEN err(113)
  21. ELSE OPB.CheckAssign(x^.left^.typ, y)
  22. END;
  23. ...
Нужно убрать часть, связанную с присваиванием временной переменной. Получим
Код: "OBERON"
  1. PROCEDURE ForOriginal;
  2. BEGIN
  3. OPS.Get(sym);
  4. IF sym = ident THEN qualident(id);
  5. IF ~(id^.typ^.form IN intSet) THEN err(68) END ;
  6. CheckSym(becomes); Expression(y); pos := OPM.errpos;
  7. x := OPB.NewLeaf(id); OPB.Assign(x, y); SetPos(x);
  8. CheckSym(to); Expression(y); pos := OPM.errpos;
  9. IF (y^.typ^.form IN {Undef, Bool, Char}) THEN err(113)
  10. ELSE OPB.CheckAssign(x^.left^.typ, y)
  11. END;
  12. ...

Вот собственно и всё!
Проверим на программе ASCII из подсистемы ZXDev:
Код: "OBERON"
  1. MODULE ASCII; (** portable *)
  2. IMPORT Console;
  3. VAR
  4. n,b: INTEGER;
  5. BEGIN (*$MAIN*)
  6. b:=127;
  7. FOR n := 35 TO b DO b:=0; Console.WriteCh(CHR(n)) END;
  8. END ASCII.


Результат - выдача одного символа # (CHR(35)), т.е. трюк с изменение значения b сработал.

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


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

Сообщения: 146
Вполне вероятно, что такой цикл и не следовало делать. Авторское описание языка, конечно, из-за краткости не обладает юридической точностью и сторонние разработчики могут трактовать его по-разному, но, возможно, недаром слова "given number of times" коллектив переводчиков перевёл как "фиксированное число раз".
Обратите внимание на эквивалентный код
Код: "OBERON"
  1. v := beg; WHILE v <= end DO S; v := v + inc END
Если воспринимать код как потенциально рабочий, а не просто псевдокод, то "S" - это вызов процедуры без параметров, который не может изменить переменные из условия цикла, если они локальные. Так что для общего случая эквивалентный код указывает соответствие с неизменными границами и нетронутой контрольной переменной. Всё, что выходит за описанное поведение можно считать неопределённым поведением(его же не определили), а неопределённое поведение можно трактовать как ошибку, в том числе и на этапе трансляции.


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

Сообщения: 273
Откуда: Россия
Comdiv писал(а):
Если воспринимать код как потенциально рабочий, а не просто псевдокод, то "S" - это вызов процедуры без параметров, который не может изменить переменные из условия цикла, если они локальные.
Это очень важная оговорка, и, будь это так, в тексте были бы пояснения. В предыдущих ревизиях, где используется временная переменная, семантика задана похоже:
Код: "OBERON"
  1. v := beg; lim := end; WHILE v <= lim DO S; v := v + inc END
Тоже используется S, хотя никаких причин ограничиваться процедурой без параметров.
Синтаксис во всех редакциях задан как
Код: "OBERON"
  1. ForStatement = FOR ident ":=" expression TO expression [BY ConstExpression] DO StatementSequence END
Значит S - это StatementSequence, т.е. последовательность операторов. Так что, S - это просто тело цикла (StatementSequence - любая последовательность операторов). Предполагать иное не из чего.

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


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

Сообщения: 146
Предполагать-то как раз можно что угодно - в этом недостаток. В описании не сказано, что соответствие проводится между общими синтаксическими конструкциями, поэтому можно предположить, что соответствие проводится между частными случаями, оставляя остальные варианты в рамках неопределённости. Если же S - это произвольный список операторов, то и о неизменности lim нельзя утверждать.


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

Сообщения: 273
Откуда: Россия
Comdiv писал(а):
Предполагать-то как раз можно что угодно - в этом недостаток.
Да, но предположения должны на чем-то основываться. Без веских оснований можно предположить необходимость совершать троекратное приседание со звуком "Ку-у!", обратившись лицом на северо-восток всякий раз при употреблении в своей программе цикла FOR. :D Ведь в сообщении о ЯП Оберон-7 не сказано, что так делать не следует, а значит, всегда остается место для неопределенности относительно этого ритуала. ;) Однако, такое предположение слишком уж фантастично и безосновательно.
А вот предположения,
что синтаксис и семантика, размещенные в разделе об одном и том же операторе, описывают одно и то же;
что тело цикла FOR такое же, как у циклов WHILE и REPEAT...UNTIL;
что Оберон-7 в основном похож на прочие обероны;
что столь важное нововведение, как необходимость телу цикла FOR состоять только из одного вызова процедуры без параметров, должно быть описано в тексте хотя бы одной фразой
выглядят достаточно разумными, чтобы предположить, что при переходе к новой версии только убрали временную переменную, оставив остальное как было. Поэтому весьма сомнительно, что S - это только вызов процедуры без параметров. Скорее уж это то же самое, что было всегда - список произвольных операторов.

Цитата:
Если же S - это произвольный список операторов, то и неизменность lim нельзя предполагать, если не сказано иное.
lim-скрытая временная переменная, нигде не присутствующая в самом FOR, поэтому недоступная для воздействия программиста. Воздействовать можно только на переменную цикла v. Возможно, предполагалось, что программист сам не будет использовать трюки, или сам выделит какую-то переменную и перед циклом выполнит присваивание ей граничного выражения, если это выражение может измениться во время цикла. Но тогда и сборщик мусора не нужен, если программист сам удаляет и выделяет память без ошибок. В том и смысл хороших компиляторов (и разумно продуманных ЯП), что человеку свойственно ошибаться, а компилятор и конструкции языка должны от этого предостеречь. "Скрытый магический механизм" управления переменной цикла, недоступный для воздействия программиста, приближает такой цикл к высокоуровневой абстракции, такой, например, как сумма (сигма большое). Ведь никто не спрашивает, чему равно i после вычисления суммы в математической формуле - это так же бессмысленно, как спрашивать, чему равна нижняя закорючка у буквы сигма, если ее отломить. А вот явный механизм, как в С или в Обероне-7, позволяет "залезть внутрь", а значит и позволяет легче совершить ошибку.

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


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

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


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

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


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

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