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

Твердыня модульных языков
Текущее время: 18 апр 2024, 04:12

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




Начать новую тему Ответить на тему  [ Сообщений: 15 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Цикл FOR. Следовать ли стандарту?
СообщениеДобавлено: 28 фев 2013, 17:07 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Попробовал пример, с разными границами цикла. Получил зацикливание при
Код: "OBERON"
  1. FOR byte := 60 TO P.Unsigned(255) DO

Это дефект не ZXDev и не беззнаковых данных. Это общая проблема цикла FOR в Оберонах, как уже обсуждалось на форуме oberoncore.
Но в данной системе проблема усугубляется еще и путаницей со знаковыми и беззнаковыми числами.
В Турбопаскале и СпектрумБейсике такой проблемы c FOR не было.
Предлагаю в ZXDev отступить от стандартной обероновской реализации FOR через WHILE и реализовать так, чтобы FOR x := A TO B обработало все значения в указанных границах, даже если B - это максимальное значение для данного типа.

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


Последний раз редактировалось Saferoll 02 мар 2013, 07:16, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 28 фев 2013, 19:28 
Не в сети
Аватара пользователя

Сообщения: 1019
Откуда: Днепропетровская обл.
Saferoll писал(а):
Предлагаю в ZXDev отступить от стандартной обероновской реализации FOR через WHILE и реализовать так, чтобы FOR x := A TO B обработало все значения в указанных границах, даже если B - это максимальное значение для данного типа.
Но тогда мы потеряем совместимость со стандартом Оберона-2. Хотя велика ли потеря? Надо подумать. Я уже писал пару раз в рассылки, удивлялся насчёт этого момента. Отвечали что-то вроде “Если отступить от стандарта, то это будет уже не совсем Оберон”, в таком духе.

Да, FOR v := n TO m интерпретируется согласно стандарту Оберона-2 как WHILE n <= m, т.е. цикл с конечным значением FOR byte := P.Unsigned(0) TO P.Unsigned(255) никогда не закончится, потому что byte ВСЕГДА будет <= 255. Конечно это несколько отличается от реализации FOR в других языках, и мне самому вот этот момент не очень нравится, но что поделать. Для цикла от 0 до 255 придётся использовать WHILE/DO, REPEAT/UNTIL или LOOP.
Код: "OBERON"
  1. VAR
  2. byte: SYSTEM.SHORTCARD;
  3. BEGIN
  4. byte := -1; REPEAT
  5. INC(byte);
  6. ...
  7. UNTIL byte = 255;
Что, кстати, почти всегда даст более компактный и быстрый код, чем FOR (FOR вынужден проверять возможность вхождения в цикл, поэтому содержит минимум два перехода, REPEAT/UNTIL же — всегда один; кроме того, для неконстантного (вычисляемого) выражения TO m заводится внутренняя переменная) [Позже было установлено, что Ofront заводит внутреннюю переменную в любом случае, очевидно, перекладывая всю оптимизацию на плечи сишного компилятора].

ОК, я не возражаю против отступления от стандарта, но нам надо придумать во что превратить сишный while(n <= m), в который транслируется обероновский FOR.


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 01 мар 2013, 08:50 
Не в сети
Аватара пользователя

Сообщения: 1019
Откуда: Днепропетровская обл.
Посмотрел как сделан цикл FOR в TurboPascal и Delphi:
Код: "EMPTY"
; Turbo Pascal
mov byte_A03, 0 ; Начальное значение счётчика
mov byte_A04, 0FFh ; Конечное значение счётчика
mov al, byte_A04
mov [bp+var_1], al
mov al, byte_A03
cmp al, [bp+var_1]
ja short locret_64
mov byte_A02, al
jmp short loc_34
 
loc_30:
inc byte_A02
 
loc_34:
 
; Тело цикла
 
mov al, byte_A02
cmp al, [bp+var_1]
jnz short loc_30
 
locret_64:
Код: "EMPTY"
; Delphi
xor eax, eax ; Начальное значение счётчика цикла
mov dl, 0FFh ; Конечное значение счётчика цикла
 
mov ebx, edx
sub bl, al
jb short loc_4038AC ; while (нач <= кон)
inc ebx
mov ds:byte_4054B4, al
 
loc_403875: ; CODE XREF: CODE:004038AAj
; Тело цикла
 
inc ds:byte_4054B4
dec bl
jnz short loc_403875
 
loc_4038AC: ; CODE XREF: CODE:0040386Dj
; Конец цикла

Как видим, TP делает две проверки в цикле, Delphi же действует более изощрённо: ещё до вхождения вычисляет количество повторений цикла и хранит в отдельной внутренней переменной. После некоторых раздумий чтобы не завязываться на переполнении предлагаю такие варианты. Было:
Код: "EMPTY"
	Unsigned__for__1 = Platform_Unsigned(255); (* Конечное значение цикла *)
Unsigned_byte = 0; (* Начальное значение цикла *)
while (Unsigned_byte <= Unsigned__for__1) {
 
(* Тело цикла *)
 
Unsigned_byte += 1;
}
(И здесь мы видим, что Ofront всегда хранит конечное значение счётчика цикла во внутренней переменной, даже если оно — константа. Есть где поработать над оптимизацией!)

Вариант 1:
Код: "EMPTY"
	Unsigned__for__1 = Platform_Unsigned(255); (* Конечное значение цикла *)
Unsigned_byte = 0; (* Начальное значение цикла *)
while (Unsigned_byte <= Unsigned__for__1) {
 
(* Тело цикла *)
 
if (Unsigned_byte == Unsigned__for__1) break;
Unsigned_byte += 1;
}
Сразу напрашивается оптимизация: вставку с break предпринимаем только в том случае, если: a) конечное значение цикла неизвестно в момент компиляции; b) оно известно и заведомо равно MIN(VARTYPE) если счётчик цикла убывает, и MAX(TYPE) в случае приращения счётчика. Но сперва надо вообще ввести оптимизацию чтобы не хранить в переменной Unsigned__for__1 константу, известную на этапе компиляции.

Кстати, эта задачка пересекается с ещё не реализованным поведением MIN(UTYPE)/MAX(UTYPE).

Вариант 2:
Код: "EMPTY"
	Unsigned__for__1 = Platform_Unsigned(255); (* Количество повторений цикла - 1 *)
if (Unsigned__for__1 >= 0) {
Unsigned_byte = 0; (* Начальное значение цикла *)
do {
 
(* Тело цикла *)
 
Unsigned_byte += 1;
} while (Unsigned__for__1-- != 0);
}
Опс, а я совершенно забыл о шаге цикла не равном 1 или -1. Это тоже обязательно нужно учесть.

Ещё такое поведение FOR надо обязательно сделать опциональным (и выключенным по умолчанию), опять же из соображений совместимости со стандартом.

Saferoll, если не хотите сами заняться этой доработкой, я добавлю себе в todo, но не обещаю сделать быстро. Здесь ещё есть над чем подумать.


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 01 мар 2013, 10:46 
Не в сети
Аватара пользователя

Сообщения: 1019
Откуда: Днепропетровская обл.
Прочитал ветку на Оберонкоре. Да, этот вариант вроде бы ничего:
FOR v := 0 TO P.Unsigned(255) BY 1 DO statements END;
Код: "OBERON"
  1. v := 0; (* Начальное значение счётчика цикла *)
  2. temp := P.Unsigned(255); (* Конечное значение счётчика цикла *)
  3. step := 1; (* Шаг приращения счётчика (со знаком) *)
  4. IF step > 0 THEN
  5. IF v <= temp THEN v := v - step; REPEAT v := v + step; statements UNTIL v >= temp END;
  6. ELSE
  7. IF v >= temp THEN v := v - step; REPEAT v := v + step; statements UNTIL v <= temp END;
  8. END;

В ходе исполнения кода v := v - step; REPEAT v := v + step может возникнуть заём 0-1 и переполнение 255+1 (65535+1), что вобщем-то не должно вызвать проблем при работе Си-программы.


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 02 мар 2013, 11:24 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Zorko писал(а):
ОК, я не возражаю против отступления от стандарта...

Жаль... :) Жаль, что так легко согласились. Потому что я уже приготовил доводы, убеждения, компромат собрал ( ;) ) и что - зря? Сколько времени потратил на сооружение тарана, а ворота распахнуты - велкомен?
Ничего-о, я все равно стандарт раскритикую, другие тоже достойны просветления. :)

Ну вот хотя бы к этому придерусь:
Цитата:
Ещё такое поведение FOR надо обязательно сделать опциональным (и выключенным по умолчанию), опять же из соображений совместимости со стандартом.

Думаю, что надо включить по умолчанию. Хотя бы включить. А лучше вообще без возможности отключать. А еще лучше не только в этой системе, но и во всех Оберонах. Ибо плохой это стандарт, неверный, неразумный, ошибочный. А уж в ZXDev и вовсе не к месту.
С каким самым первым ЯП сталкивается пользователь Спекки? ...? Да-да, наш любимый примитивный, неструктурный, немодульный, но именно его зашил в эту волшебную коробочку сэр Клайв (даже еще и не будучи сэром). И какой в этом языке штатный оператор цикла (и единственный,кстати)? ...? Угу-именно он! И если мы будем портировать игру на ЛазерБейсик, то в какой оператор Оберона он отобразится? Риторически! Запустим мы этот порт и получим.... Хотя все вроде верно. Так ведь это стандарт Оберона - зацикливание получать! :evil:
Мы пока что изменяем FOR только в трансляции через Ofront, а модули составляющие сам ББ скомпилированы по стандарту. И это нормально, что есть особенности для наших специфических целей. Зато проблем с таким FOR гораздо меньше. Разве лучше, опцию по умолчанию выключить, чтобы все ее всегда включали вручную? По умолчанию должен быть самый употребительный вариант, а здесь он - "незацикливающийся FOR". Вот экран у нас 256 точек, поставили в цикле обработку - на правом краю экран завис. Завели буфер для фрагментов в 256 байт. Если выбираем фрагмент примыкающий к концу буфера ( TO 255) - зависание!
Для вас не звучит странно "По стандарту оператор FOR в Обероне иногда должен зависать, поэтому это опция по умолчанию. Но если вы хотите, чтобы FOR мог выполниться для любых значений параметров, то переключите опцию"?

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


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Цикл FOR. Следовать ли стандарту?
СообщениеДобавлено: 02 мар 2013, 11:53 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Zorko писал(а):
Но тогда мы потеряем совместимость со стандартом Оберона-2. ... Я уже писал пару раз в рассылки, удивлялся насчёт этого момента. Отвечали что-то вроде “Если отступить от стандарта, то это будет уже не совсем Оберон”, в таком духе.
ИМХО, если следовать такому стандарту, то вот тогда будет не совсем Оберон.
Раз уж стандарт задает семантику FOR через эквивалентный фрагмент кода на Обероне, то, тем самым, стандарт задает и все особенности исполнения этого кода при разном сочетании параметров. Т.е. стандарт определяет семантику FOR так (возьмем для простоты шаг 1): "FOR x:=A TO B DO ...END выполнит тело цикла для всех значений x из отрезка A..B в возрастающем порядке. Затем, если B=MAX(T), то тело цикла будет выполняться бесконечное число раз, перебирая циклически все значения типа T." Ну, или вариант (если включен контроль за переполнением чисел): "..., то исполнение программы аварийно прервется из-за переполнения".
Помилуйте, это стандарт?! :o Стандарт разумного, ясного, компактного, регулярного ЯП Оберон?!! Это на баг-репорт больше смахивает! И то, что это изложено не словами, а операторами языка, дела не меняет.

Контроль за переполнением типов находится за рамками самого ЯП? Ладно, пусть так. Но ограниченность множества значений целочисленного типа язык осознает? См п.6.1. Язык программирования Оберон-2
Цитата:
3. SHORTINT целые в интервале от MIN(SHORTINT) до MAX(SHORTINT)
4. INTEGER целые в интервале от MIN(INTEGER) до MAX(INTEGER)
5. LONGINT целые в интервале от MIN(LONGINT) до MAX(LONGINT)

На разных платформах эти границы разные, но они везде есть, потому что заданы стандартом! В операторе FOR x:=A TO B x,A,B могут принимать любые значения из типа, которому принадлежат, в т.ч. и максимальное. И если B=MAX(T), то последняя итерация выполнится для x=MAX(T). А потом стандарт требует инкремент — х должно принять значение на 1 больше чем максимально возможное. И вот тут будет или бесконтрольное переполнение, или аварийный выход или...Что еще можно придумать? Ну например, инкремент не изменит в этом случае значение x (такая вот реализация — барьер там стоИт). Но во всех этих трех реализациях будет или зацикливание или АВОСТ. Т.е. С одной стороны Оберон говорит, что для переменной есть максимальное значение, с другой стороны приказывает и в этом случае выполнять инкремент. Что при этом случится зависит от реализации, это вне ЯП. Но уж понимать, что при любой реализации ничего хорошего от превышения не получится, это-то в рамках языка?
Код: "OBERON"
  1. VAR x,A,B:T; (* все эти величины принимают значения в границах типа Т*)
  2. (*здесь А и В получает какие-то значения в границах Т*)
  3. FOR x := A TO B DO (* выполняется некая обработка в границах A..B, а поскольку
  4. А,В в границах T, то и обработка, как логично ожидать, будет
  5.   протекать только в этих границах*)
  6. END;

Задача четко сформулирована, вроде бы нигде выхода за границу не видно (в том числе и при В=МАХ(Т)). А получаем в некоторых случаях либо зацикливание, либо ТРАП! Почему? А потому, что после обработки последнего элемента x=B задача уже выполнена, тут бы и прекратить работу — это была бы самая разумная, естественная семантика цикла. Нет же, по стандарту надо после этого выполнить инкремент. Зачем? Зачем брать следующий элемент, который мы не должны обрабатывать (и который в данном частном случае вообще не существует!)? Тебе разрешили съесть 10 конфет, а ты 10-ю съел и за 11-й потянулся? Не съел, но ведь взял же, взял! Так ведь дадут по рукам-то! И правильно сделают, давно по рукам врезать пора!

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


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Цикл FOR. Следовать ли стандарту?
СообщениеДобавлено: 02 мар 2013, 14:35 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Сказка о Великом Стандарте
Представим, что задали ученику такую задачу:
Код: "EMPTY"
Связное подмножество целых чисел T задано своими границами MIN(T)..MAX(T). Связная подобласть этого подмножества задана границами А..B (MIN(T)<=A,B<=MAX(T)). 
Требуется обработать все элементы подобласти в возрастающем порядке (если A>B, то подобласть считать пустой и ничего с ней не делать).

Часто встречающаяся задача, правда? В строке обработать подстроку, в массиве подмассив и т. д.
Вот написал наш ученик программу (через WHILE), стали ее запускать. Всё хорошо - пустую подобласть обрабатывает, область в левом краю Т тоже, в середине тоже... А вот когда обрабатываем правый край Т (когда B=MAX(T)) – зависает! Что это, ошибка? Ну так-то да, типичная ошибка при обработке линейной структуры - «out of range”/”плюс-минус 1” - не учтена специфика граничных элементов (в данном случае последнего, а иногда первый тоже надо как-то особо обработать).
Можно поставить «незачет» и заставить исправить. Но если ученик — любимое чадо высокопоставленного отца, то... То может лучше глаза закрыть на такую недоработку? Ведь частично же работает, не всегда же подобласть справа будет или всё T займет. Массивы с нуля нумеруются, память ограничена, диапазон Т велик — так может массив туда и не дотянется, может и не понадобится нам MAX(T) обрабатывать?
А придется...так что же, скажем «фича это такая, особенность», не дОлжно на всю область рот розевать, надо хоть 1 элементик в конце нетронутым оставить. Если применяете для обработки всего Т (или подобласть на правом краю), то сами и виноваты, что не умеете под эту ошиб...э-э-э особенность подстраиваться! А чтоб уж все подстроились, программу эту для обработки подобласти в стандарт возведем, чтоб и у всех так же было. А то что ж, одни элементик последний оставляют, а другие всё обрабатывать горазды? Пусть теперь у всех задача об обработке подобласти на краю зависает!

Ну а теперь задачу эту назовем «реализация оператора FOR”, ученика Обероном наречем, его родитель(ли) … - сами-знаете-кто :) , а стандарт...Стандарт на то и стандарт, чтоб не меняться, он так стандартом и останется.
«Да здравствует созданный волей народной Великий Могучий Стандарт Оберо-о-о-н! Сла-а-а-вься-а-а...»

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


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 02 мар 2013, 19:20 
Не в сети
Аватара пользователя

Сообщения: 1019
Откуда: Днепропетровская обл.
Saferoll писал(а):
Zorko писал(а):
ОК, я не возражаю против отступления от стандарта...

Жаль... :) Жаль, что так легко согласились. Потому что я уже приготовил доводы, убеждения, компромат собрал ( ;) ) и что - зря? Сколько времени потратил на сооружение тарана, а ворота распахнуты - велкомен?
Ладно-ладно, я ведь не для себя согласился, а потому что знаю, что хорошо идти на компромиссы с единомышленниками, тем более, если это решаемо.

Но если требуются аргументы против, то пожалуйста. :)

Я полагаю, что актуальность данного вопроса в контексте 32-битных платформ незначительна, и вот аргументация. Если в качестве счётчика цикла использовать 32-битные и больше целые, то вероятность достижения TO MAX(INTEGER), а уж тем более TO MAX(LONGINT) невероятно мала, стоит очень напрячь мозг, чтобы получить задачу, где такое значение действительно потребуется.

В то же время использовать в качестве счётчика цикла переменную типа SHORTINT или BYTE особого смысла нет, т.к. это не даёт никаких преимуществ на 32-битных платформах. Собственно, Ofront даже не даст использовать переменную типа SYSTEM.BYTE как счётчик цикла (и наверное это правильно).

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

Однако ситуация крайне меняется если нужно программировать 8- и 16-битные процессоры. Здесь уже без маленьких типов данных обойтись не получится (из соображений эффективности), и соответственно нужно с ними как-то работать. Здесь проблема имеет место. Именно в таком проекте как XDev. Но 99% оберонщиков назовут это несущественным тоже, ибо им уже не нужны такие процессоры. Получается, желание ворошить стандарт исходит из практической необходимости разрабатывать под старинные процы, как я понимаю. Ну и что я должен был ответить? Отказаться реализовывать? :P Гм, так там ещё покумекать надо. Вот мне не нравится заём и переполнение счётчика цикла. В ассемблере и Си ещё куда ни шло, но Оберону приличествует обрабатывать такие ситуации (хотя бы в отладочном режиме, если не всё время).

Saferoll писал(а):
Для вас не звучит странно "По стандарту оператор FOR в Обероне иногда должен зависать, поэтому это опция по умолчанию. Но если вы хотите, чтобы FOR мог выполниться для любых значений параметров, то переключите опцию"?
Звучит-звучит. :) Но поправочка. "Хотите вкусного FOR'а — юзайте волшебную опцию и наслаждайтесь. Но если хотите, чтобы это ещё и не зависало на других Оберонах — тогда уж помилуйте. И не говорите, что мы вас не предупреждали." ;)

Увы, со стандартами приходится считаться, хотя они и не всегда хороши. И, кстати, не могу не пойти навстречу юзеру ZXDev, ибо нас так мало. ;)

Ну а Вирту своейственно избегать проблем и оставлять их за спиной, без внимания. Видишь, ввели пару сущностей, чтобы работать с беззнаковыми — уже сколько появилось тонких моментов. Тут, опять же, FOR — просто массу проблем порождает. Например, можешь сходу ответить: FOR i := 1 TO Fn() DO — выполнит Fn() один раз? Или столько, сколько раз исполнится цикл? Хорошо, что мы это знаем, но если не знать семантики языка, то из самой записи это не следует.


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 02 мар 2013, 23:31 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Zorko писал(а):
Я полагаю, что актуальность данного вопроса в контексте 32-битных платформ незначительна, и вот аргументация. Если в качестве счётчика цикла использовать 32-битные и больше целые, то вероятность достижения TO MAX(INTEGER), а уж тем более TO MAX(LONGINT) невероятно мала, стоит очень напрячь мозг, чтобы получить задачу, где такое значение действительно потребуется.
Не забывайте, что проблема имеет место, когда B=MAX(LONGINT) или MAX(INTEGER), граница А в этом случае может быть любой (потому что всегда А<=B=MAX(LONGINT) ), т.е. сама подобласть может состоять всего из нескольких чисел (например MAX(INTEGER)-10 TO MAX(INTEGER)), но сами числа очень большие - максимальные. Конечно, это вряд ли индексы массива. Но почему не параметры в каком-то целочисленном вычислении: датчик СЧ, криптография, поиск целых с заданными свойствами... Например, 2^32-1 - это двоичный репьюнит,он особыми свойствами обладает, может быть потребуется сделать какие-то вычисления вблизи этого числа?
Вот получила ракета закодированную команду, взяла очередной случайный ключ (а он как назло сегодня MAX(LONGINT)!), выполнила в алгоритме расшифровки FOR вблизи этого числа и ... Жалко, миллиарды долларов стоила. Ну не протестировали, потому что по матпостановке ключ К в алгоритме для любого числа LONGINT справедлив. Поэтому особо не проверяли, понадеялись что достаточно VAR K:LONGINT;
Цитата:
Однако ситуация крайне меняется если нужно программировать 8- и 16-битные процессоры. Здесь уже без маленьких типов данных обойтись не получится (из соображений эффективности), и соответственно нужно с ними как-то работать.
Да, для Z80 и прочих "малышей" это особенно актуально. Хотя, повторю, свалится в эту "каверну" на любой системе можно.
Цитата:
Так что, как видим, проблемы нет.
Да есть проблема-то, и как я понял, агромадная! Она даже фундаментальней чем цикл FOR, это проблема методическая.
Цитата:
Достаточно просто знать, что цикл FOR реализован без учёта конечного значения переменной, и использовать это.
А многие обероновцы знают? А многие из мэтров (хотя бы с oberoncore) осознают такие особенности своих программ, принципиально не употребляя FOR, но воспроизводя через WHILE эквивалентную "стандартную" конструкцию (и,конечно, с таким же дефектом)? И многие пишут в документации к модулям кроме VAR N:INTEGER еще и N<MAX(INTEGER) или ставят это условие в ASSERT? Это и есть методическая проблема.
Цитата:
Вернее, редко с этим сталкиваться, и если очень уж повезёт.
Читайте выше про ракету, ей сегодня "повезло". А могло бы "повезти" через год. Это хорошо, когда такая бомба замедленного действия есть? Ведь Оберон позиционируется как очень надежный язык, с доказательствами правильности, с выводом свойств, с пред- и постусловиями. А когда легче все это выводить: когда утверждения справедливы для всего множества значений или когда в области значений есть "лакуна", где особые (и "некрасивые") свойства? Если в программе написано VAR N:INTEGER;, то уж вряд ли в N будет что-то другое, за этим компилятор внимательно следит. И если какое-то свойство справедливо для всех INTEGER, то и проверять ничего особо не нужно, всё будет само собой. А вот если дополнительно нужно N<MAX(INTEGER), то нужны спецповерки, ASSERT или еще что-то. А если таких параметров несколько, как проявится их сочетание? Пред\пост-условия превращаются в многоэтажную конструкцию из дизъюнктов и конъюнктов, из которой ничего полезного уже не вывести. Ну не работает интуиция на таких запутанных вещах, ей что-то "красивое", регулярное, "разумное" нужно!
Да и с какой стати мы должны отбрасывать значение MAX? Ну ради чего? Ради старой ошибки стандарта? Давайте лучше ошибку отбросим!
Цитата:
Подсчитанный нами десятитысячелетний срок означает, что за время своего существования умножитель должен будет выполнить только ничтожную часть огромного числа всех возможных перемножений, на которые он способен: практически ничего он сделать не успеет. Как ни странно, мы все же требуем, чтобы он был способен правильно выполнить любое перемножение, если поступит соответствующий приказ. Это фантастическое качество требуется потому, что мы не знаем заранее, какие именно ничтожно малые по своему количеству умножения потребуется выполнить.(Э.Дейкстра.Структурное программирование)
А вот еще вспомнилась Ошибка Pentium FDIV. Intel тоже пыталась за фичу выдать, "потому что чисел много и вероятность получит ошибку крайне мала, менее вероятности быть убитым метеоритом (хотя если вы знаете куда упадет метеорит, вы можете встать на это место)"(точную цитату не помню и сразу в Инете не нашел, но смысл такой). И что? Скандал поднялся и "фичу" исправили, потому что это явный баг. Процессор должен без ошибок любые числа делить, а FOR в любых границах итерации выполнять!
Цитата:
Ну и что я должен был ответить? Отказаться реализовывать? :P Гм, так там ещё покумекать надо. ...
И, кстати, не могу не пойти навстречу юзеру ZXDev, ибо нас так мало. ;)
Должен был согласиться. :) И я рад, что согласился. :D Про "жаль..." - это шутка была. ;) Хотя...действительно хотелось вызвать на дискуссию. Ну как-то неинтересно всё монологи разводить, какой-то обратной связи хочется. :)
Цитата:
Вот мне не нравится заём и переполнение счётчика цикла. В ассемблере и Си ещё куда ни шло, но Оберону приличествует обрабатывать такие ситуации (хотя бы в отладочном режиме, если не всё время).
Переполнение в цикле происходит от неверной организации цикла - после обработки последнего элемента не нужно брать следующий (выполнять инкремент). А само переполнение...Мы работаем на 8-разрядном процессоре, переполнения не избежать. Управлять...ну вроде в самом Обероне управления нету, выходит за рамки языка. Разве что спецSYSTEMпроцедуры написать, чтоб ассемлерные макросы вставлять.
Погоди-ка, что ты сказал?! "Си"?! Ну конечно же, СИ! Вот откуда всё это тянется-то... :shock:
Ведь стандартный обероновский FOR это эквивалент сишного for(x=A;x<=B;x++); Перешли на структурный ЯП, и дефектный шаблон из Си протащили.
Так-так, говорил же, методическая проблема, в головах, в мышлении, в инерции - вот где главное зло.
Цитата:
Но поправочка. "Хотите вкусного FOR'а — юзайте волшебную опцию и наслаждайтесь. Но если хотите, чтобы это ещё и не зависало на других Оберонах — тогда уж помилуйте. И не говорите, что мы вас не предупреждали." ;)
Поправочка к поправочке "...Но если хотите, чтобы это ещё и зависало на других Оберонах" Ведь стандарт-это зависание в некоторых случаях, волшебная опция зависание убирает. А где не зависало, там без разницы - полностью так же работает.
Цитата:
Увы, со стандартами приходится считаться, хотя они и не всегда хороши.
Ну зачем считаться с плохими стандартами, чтоб всем стандартно плохо было?
Цитата:
Тут, опять же, FOR — просто массу проблем порождает. Например, можешь сходу ответить: FOR i := 1 TO Fn() DO — выполнит Fn() один раз? Или столько, сколько раз исполнится цикл? Хорошо, что мы это знаем, но если не знать семантики языка, то из самой записи это не следует.

Если не знать семантики, то из любой записи ничего не следует, потому что семантика - это и есть смысл. Я не против задания семантики фрагментом кода на Оберон. Я говорю, что в этом фрагменте для FOR ошибка, он должен быть другой, правильный. Чтобы все значения границ обрабатывал и не зацикливался. А какой именно, надеюсь скоро написать.

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


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: О границах параметра цикла FOR
СообщениеДобавлено: 03 мар 2013, 10:49 
Не в сети

Сообщения: 25
По ходу, "лишний" инкремент может иметь смысл, если трактовать параметр как указатель позиции. Который должен иметь также положение "после конца" (и, кстати, "до начала" тогда уж :)). Так у Мейера в Эйффеле, где-то в этой книге объяснялось (в главе о типах вроде). Что не отменяет проблем...


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

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


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

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


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

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