Comdiv писал(а):
Сколько раз Вам нужен был "правильный" FOR. У меня не встречается таких циклов, для которых было бы удобно его ипользовать, а сколько у Вас и других людей, в частности Олега? Можете посчитать?
Лучше подсчитать случаи, когда кому-то был очень нужен эффект зацикливания FOR на краю диапазона.
Предположим есть комната с прочным полом по всей ее площади и есть точно такая же, где в дальнем углу дыра. Возможно, площадь комнаты настолько огромна, а задачи настолько локальны, что в этот дальний угол очень редко кто заходит, поэтому разницы чаще всего нету. Ну а вдруг? Лучше уж пусть везде будет прочный ровный пол.
Цитата:
Вы вполне можете реализовать желаемое поведение и для WHILE, или по крайней мере можете трактовать FOR с такой границей как WHILE, в котором переполнение приводит именно к такому результату.
В том и дело, что в стандарте конструкция WHILE для цикла FOR строго задана, т.е. вместо FOR в таких-то и таких-то случаях нужно использовать WHILE. Сравните описания "цикл FOR только для В<MAX(T)" и "цикл FOR для любых значений T", какое лучше? Или аналогия: "ходите везде, кроме вон того угла" против "ходите в этой комнате где угодно". Зачем нам лишние дырки? Чтобы не скучно было с оглядкой ходить? Лучше оператор "для любого целого типа" или "для любого, кроме"?
Деление на ноль никуда не денешь, но здесь-то зачем особенности терпеть? Если их можно легко устранить.
Не понимаю, зачем нужен цикл ограниченный по диапазону возможных значений, если можно создать цикл с более широкой областью определения (без оговорок и особенностей)?
Хотя, конечно, лукавлю, прекрасно понимаю: 1)легче задать семантику через эквивалентный WHILE-цикл 2)проще компилятор 3)зачем мудрить, если в большинстве случаев и так всё работает, а особые случаи можно перехватить и отдельно обработать
Comdiv писал(а):
Явное оговаривание - это + к точности определения, но неопределённый эффект он и без явного оговаривания будет неопределённым, главное, чтобы читатель описания языка - создатель транслятора не превращался в итальянского забастовщика.
Как говорит госпожа Мизулина "Запрет-это свобода"
Запрет изменять переменную цикла или ожидать какого-то ее постзначения есть свобода компиляторостроителя выбирать механизм реализации такого цикла. И получается довольно эффективно.
Запрет, по сути дела описание "гарантийного случая", где разработчик гарантирует определенное поведение в некоторых рамках. Что за рамками - извините, сами виноваты. И запрет этот не просто наугад с потолка списан, а из соображений структурного программирования (вроде запрета goto). Если не трюкачить с переменной цикла, то получится хорошая абстракция (сумма, кванторы и пр.), что полезно для верификации программ, вывода программ из формул и т.д.
Comdiv писал(а):
Или как вариант - диагностика компилятора на изменяемое выражение, что не противоречит текущему описанию.
Не думаю, что это лучше. Выражения, определяющие границы диапазона, могут быть сложными, содержащими много переменных. Почему мы должны запрещать всем им меняться (или как-то это перехватывать?) Лучше просто присвоить конечно значение скрытой временной переменной.
Comdiv писал(а):
На всякий случай уточню, что в Обероне нельзя менять переменную другого модуля.
В КП, например, можно сделать переменную экспортируемой и в другом модуле ее поменять. Чтобы нельзя было менять, надо вместо звездочки поставить минус.
Comdiv писал(а):
Как по мне, для реализации транслятора O7 лучше оставить всё как есть, но трактуя неопределённое поведение как ошибки времени трансляции или хотя бы исполнения, а уж в новых языках/диалектах можно сделать и радикально.
Именно так мы с Zorko и делаем. Но я изучаю и сравниваю реализации цикла FOR в разных ЯП (не только в Оберонах). И считаю, что "духу Оберона" стандартный цикл не соответствует, а мой FOR гораздо лучше
Comdiv писал(а):
К слову, описанный Вами FOR - это, ведь, тоже синтаксический сахар для чего-то подобного
Код: "OBERON"
v := beg;
lim := end;
IF v <= lim THEN
S;
WHILE v < lim - inc DO
v := v + inc;
S
END
END
Вот в том всё и дело, что это не синтаксический сахар! Я употребил этот термин в том смысле, что FOR в Оберон-7 однозначно разворачивается в эквивалентную конструкцию с циклом WHILE просто текстуально, без всяких оговорок о скрытых переменных, одноименных идентификаторах или что-то там еще. В КП и Оберон 2, это не так, там надо делать оговорку о временной локальной переменной, которую стандартными средствами не создашь (надо заранее ее где-то описать).
Для
Код: "OBERON"
имеем beg=1, end=2, inc=1. Тогда IF 1<= 2 выполняется, поэтому выполним S(1), потом WHILE 1<2-1 не выполнится ни разу, хотя должно быть выполнено S(2). Видимо, здесь опечатка и должно быть "WHILE v
<= lim - inc".
С этой поправкой - да, это один из возможных способов. Но, опять таки это не сахар, и я против описания семантики через эквивалентный фрагмент. Например, в этом фрагменте видно чему равна переменная по окончании цикла и что будет, если изменить переменную. Лучше, если этот механизм будет полностью скрыт. Тогда трюки станут явным нарушением, значит программы будут более структурные и доказываемые (и выводимые из свойств), а механизм можно выбрать наиболее эффективный для каждого случая.
Цитата:
Хотя, пожалуй, Вы не описали поведние FOR, когда верхняя граница недостижима, потому что перепрыгивается
Не совсем понял, про что это. Если про случай, когда beg>end, то да, лучше такую оговорку сделать явно "если beg>end, то цикл не выполниться ни разу". Формально, это заключено в словах "выполнится верное количество раз для любых значений А,В" потому что при А>B это верное количество равно нулю.
А если про случай, когда В=MAX(T), а переменная эту границу перепрыгивает, то тут тоже все описано. Верное количество раз равно (B - A) DIV inc +1 (вычисленное точно, без переполнений, даже если это количество превышает MAX(T)), а конечное значение переменной цикла не определено (поэтому неважно, что числа MAX(T)+inc-k в диапазоне нет). Здесь k-некоторое число, которое определяет насколько v выскочило за пределы диапазона Т (вернее, выскочило бы, если бы не ограничение диапазона).