Axcel писал(а):
Ну, в общем понятно, ответа нет.
Блин, ну сколько в открытые двери можно ломиться???
Вы читайте, что пишут! Я же говорил, что при отражении модели в языке, нам часто нет необходимости в цикловой переменной.
Есть операции, в которых она ПРОСТО НЕ НУЖНА
ПО СМЫСЛУ.
Например (от лихтарыка):
Collection.ForEach и Collection.Find
Это - ЕСТЕСТВЕННОЕ высокоуровневое описание наших намерений относительно как всей коллекции, так и отдельных ея элементов.
Теперь встаёт вопрос о передаче фрагмента действий с элементов этой коллекции.
В простейшем случае можно обойтись ссылкой на процедуру/функцию, в аргументах которой будет "формироваться контекст" при работе с очередным элементом. Но часто бывает удобно и более естественно, передавать туда
нечто, что увяжет текущий контекст (в котором вызваны Collection.ForEach и/или Collection.Find) с контекстом самих Collection.ForEach и Collection.Find... Например, кусок кода обращается к локальным переменным процедуры вызывающей Find для сравнения полей элемента коллекции с локальными (и не только!) переменными, которые "текстуально не известны" в Find.
Часто оказывается, что такая запись проще и нагляднее.
Ещё раз повторяю, мы рассматриваем данное средство (относительно ООП) именно, как один из путей удаления лишнего уровня абстракции (семантически несовместимые по уровню абстракции) работы с переменными цикла. Плюс - повышается надёжность, за счёт удаления лишних мест, где можно получить ошибки через описки...
В си-шарпе этим "нечтом" стали "замыкания"...
Относительно решения Вирта о цикле FOR, я сказал, что работа с "массивами" (как с частным случаем классов "коллекций") оказалась "размазанной" по уровням абстракции, благодаря невключению в язык FOREACH.
Кстати, тот же поиск, в случае расширения применения EXIT для всех цикловых операторов, выполнялся и ещё таким способом:
Код:
VAR foundItem : Item = NIL;
...
FOREACH item : Item IN itemArray DO
IF Condition( item ) THEN foundItem := item; EXIT END;
END
Заметьте, что здесь ошибки быть не может с границами поиска.
Кстати, короче можно было бы записать, введи Вирт (наряду с "для каждого", операцию проверки "а есть ли?"). Но - лишних слов много... Опять-таки "лишнесть" не есть плохо или хорошо. Массив в Оберонах - не расширение какого-то коллекционного типа, в котором описанные мной операции определены, а "собственная сущность и понятие"...
Код:
VAR foundItem : Item = NIL;
startItem : Item = NIL;
...
foundItem = FINDIF( itemArray, CheckFunc, startItem );
или
foundItem = FINDIF( itemArray, CheckFunc, NIL ); //если ищем с начала
Или
Код:
VAR foundIndex : INTEGER = -1;
...
foundIndex = FINDINDEX( itemArray, CheckFunc, 0 );