Oberon space

General Category => Общий раздел => Тема начата: ilovb от Ноябрь 26, 2013, 02:25:17 pm

Название: [Oberon 07/13] Семантика FOR
Отправлено: ilovb от Ноябрь 26, 2013, 02:25:17 pm
Склоняюсь к мысли, что семантика цикла FOR должна быть примерно как в Ada/Lua, т.е.:
1. Переменную цикла запрещено объявлять в секции VAR (соответственно запрещено перекрытие имен)
2. Тип всегда INTEGER;
3. Область действия переменной - тело цикла.
4. Переменная доступна только для чтения.

Кто что думает на этот счет?
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: vlad от Ноябрь 26, 2013, 02:52:22 pm
Кто что думает на этот счет?

Согласен. Хотя специализированные варианты (foreach) все равно лучше :)
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: valexey_u от Ноябрь 26, 2013, 03:15:56 pm
Эмм... Вообще говоря да, такой цикл отлично заменяется на foreach, ибо является его частным случаем.
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: vlad от Ноябрь 26, 2013, 03:46:35 pm
Эмм... Вообще говоря да, такой цикл отлично заменяется на foreach, ибо является его частным случаем.

Да, цикл отсюда и до туда с read-only пемеренной - 99%, что писатель просто хотел пройтись по всем элементам (целочисленная переменная здесь в роли итератора), т.е. классический foreach.
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: valexey_u от Ноябрь 26, 2013, 03:50:28 pm
Эмм... Вообще говоря да, такой цикл отлично заменяется на foreach, ибо является его частным случаем.

Да, цикл отсюда и до туда с read-only пемеренной - 99%, что писатель просто хотел пройтись по всем элементам (целочисленная переменная здесь в роли итератора), т.е. классический foreach.
А если ему нужны индексы, то это тоже foreach только уже не по коллекции, а по целочисленному типу (enum, или range какой).
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: ilovb от Ноябрь 26, 2013, 04:35:01 pm
Т.е. вместо модификации FOR, предлагаете воткнуть foreach, а вместе с ним итераторы, коллекции, диапазоны и т.д...?  :)
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: Geniepro от Ноябрь 26, 2013, 04:47:20 pm
Цикл for в таком виде нинужен. Если уж и делать цикл for, так в сишном варианте.
Очень удобно, например, делать так:
for (table->begin(); ~table->eof(); table->next())
{
...
}
чем вот так:table->begin();
while (~table->eof())
{
...
    table->next();
}

А если в стиле Ады -- то да, это просто foreach с перебором коллекции (в том числе ленивой) или итератором (имитатором ленивой коллекции)...
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: ilovb от Ноябрь 26, 2013, 05:00:24 pm
А чем for лучше while в твоем примере? Вроде те же яйца, только в профиль.  ;)
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: valexey_u от Ноябрь 26, 2013, 05:07:08 pm
Т.е. вместо модификации FOR, предлагаете воткнуть foreach, а вместе с ним итераторы, коллекции, диапазоны и т.д...?  :)
Итераторы, коллекции и диапазоны - это же не языковые фичи :-) C итераторами работает обычный for, при чем тут foreach?

for(itr = mymap.begin(); itr != mymap.end(); ++itr) {
    // some code here
}

Всё явно, обычный for (а можно и while), никаких форычей.
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: Geniepro от Ноябрь 26, 2013, 05:07:36 pm
А чем for лучше while в твоем примере? Вроде те же яйца, только в профиль.  ;)

Тем что в нём инициализация цикла, условие его завершение и действие по его продвижению вперёд -- всё на виду, в одной строке, сразу всё понятно.
while'же размывает этот цикл на как минимум две части...
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: ilovb от Ноябрь 26, 2013, 05:40:25 pm
Т.е. вместо модификации FOR, предлагаете воткнуть foreach, а вместе с ним итераторы, коллекции, диапазоны и т.д...?  :)
Итераторы, коллекции и диапазоны - это же не языковые фичи :-) C итераторами работает обычный for, при чем тут foreach?

Чтобы сделать foreach как в Lua или там питоне, придется ввести в язык либо поддержку итераторов (ибо форыч должен что-то вызывать, и это что-то должно помнить на каком оно элементе находится), либо ФВП с замыканиями.

for item in collection do
...
end

что такое "collection"?  :)

for(itr = mymap.begin(); itr != mymap.end(); ++itr) {
    // some code here
}

Всё явно, обычный for (а можно и while), никаких форычей.

Ну я уже высказывался что while спокойно заменяет форыч  :)
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: ilovb от Ноябрь 26, 2013, 05:43:30 pm
Тем что в нём инициализация цикла, условие его завершение и действие по его продвижению вперёд -- всё на виду, в одной строке, сразу всё понятно.
while'же размывает этот цикл на как минимум две части...
Да, тут for несколько выигрывает.
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: valexey_u от Ноябрь 26, 2013, 05:55:12 pm
Т.е. вместо модификации FOR, предлагаете воткнуть foreach, а вместе с ним итераторы, коллекции, диапазоны и т.д...?  :)
Итераторы, коллекции и диапазоны - это же не языковые фичи :-) C итераторами работает обычный for, при чем тут foreach?

Чтобы сделать foreach как в Lua или там питоне, придется ввести в язык либо поддержку итераторов (ибо форыч должен что-то вызывать, и это что-то должно помнить на каком оно элементе находится), либо ФВП с замыканиями.

for item in collection do
...
end

что такое "collection"?  :)
Ну, если уж ты говоришь про Аду и противопоставляешь это дело форычу, то скажи ка, как на Обероне будет выглядеть вот это (это чисто Адские форы):
for Count in List loop
    Put (Count);
end loop;

Ну или такое:
for Count in My_Array_Var'Range loop
    ...
end loop;

Чтобы и сделать нормальный форыч и сделать нормальный For из Ады, нужно существенно поменять язык.
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: Geniepro от Ноябрь 26, 2013, 06:06:32 pm
Ну я уже высказывался что while спокойно заменяет форыч  :)

Ага, а if-goto спокойно заменяет while...
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: ilovb от Ноябрь 26, 2013, 06:57:03 pm
for Count in List loop
    Put (Count);
end loop;
Разве в Аде есть форыч?   ???

Я думал это обычный for.
А что такое тут List?
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: Geniepro от Ноябрь 26, 2013, 07:16:50 pm
for Count in List loop
    Put (Count);
end loop;
Разве в Аде есть форыч?   ???

Я думал это обычный for.
А что такое тут List?

Да уж, тут Валексей нам мозги запудрил ))) Вот оригинальный текст:
Цитата: http://www.ada-ru.org/V-0.4w/part_1/ch_03.html
3.6.3 Цикл for

 Еще одним распространенным случаем является ситуация когда необходимо выполнить некоторые действия заданное количество раз, то есть организовать счетный цикл. Для этого Ада предусматривает конструкцию цикла for.

 Конструкция цикла for Ады аналогична конструкции цикла for, представленной в языке Паскаль.

 Существует несколько правил использования цикла for:
тип переменной-счетчика цикла for определяется типом указываемого диапазона значений счетчика, и должен быть дискретного типа, вещественные значения - недопустимы
счетчик не может быть модифицирован в теле цикла, другими словами - счетчик доступен только по чтению
область действия переменной-счетчика распространяется только на тело цикла

 Примечательно также, что тело цикла не будет выполняться если при указании диапазона значений переменной-счетчика величина значения "нижней границы" будет больше чем величина значения "верхней границы".

for счетчик in диапазон_значений_счетчика loop

    -- инструкции тела цикла

end loop;


for  Count in 1..20 loop
    Put (Count);
end loop;


 Возможен перебор значений диапазона в обратном порядке:

for счетчик in reverse диапазон_значений_счетчика loop

    -- инструкции тела цикла

end loop;


for Count in reverse 1..20 loop
    Put (Count);
end loop;


 Любой дискретный тип может использоваться для указания диапазона значений переменной-счетчика.

declare
    subtype List is Integer range 1..10;

begin
    for Count in List loop
        Put (Count);
    end loop;
end;


 Здесь, тип List был использован для указания диапазона значений переменной-счетчика Count. Подобным образом также можно использовать любой перечислимый тип.

Тут List -- всего лишь подтип целого типа.
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: ilovb от Ноябрь 26, 2013, 07:36:15 pm
Вообще где у нас форыч есть?
Знаю что в VB, Java, Lua, Python, PHP, JS, C#, C/C++ (через макросы только)

В Lua он работает через замыкание. Сделано универсально без лишних сущностей (for in просто принимает функцию)
В Java через через методы коллекции (глубже вшито в язык чем в Lua)

Оба варианта требуют серьезных изменений в языке.
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: ilovb от Ноябрь 26, 2013, 07:40:58 pm
Вау! В 11'ых плюсах появился таки форыч: http://en.wikipedia.org/wiki/Foreach_loop#C.2B.2B
 :D
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: valexey_u от Ноябрь 26, 2013, 08:11:10 pm
Вообще где у нас форыч есть?
Знаю что в VB, Java, Lua, Python, PHP, JS, C#, C/C++ (через макросы только)
В С++98 std::for_each это не макрос, это просто функция.
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: valexey_u от Ноябрь 26, 2013, 08:12:27 pm
Вау! В 11'ых плюсах появился таки форыч: http://en.wikipedia.org/wiki/Foreach_loop#C.2B.2B
 :D
Причем заметь, обошлось без итераторов и "коллекций" вшитых в язык :-)
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: valexey_u от Ноябрь 26, 2013, 08:18:13 pm

Да уж, тут Валексей нам мозги запудрил ))) Вот оригинальный текст:
Во-первых не всего лишь. Это означает что цикл For из Ады бесполезен без её системы типов. А система типов в Аде по сложности тянет поболее чем на 16 страниц :-)

Во-вторых ты проигнорировал второй мой пример. Эти примеры НЕ идентичны.
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: Geniepro от Ноябрь 26, 2013, 08:28:17 pm

Да уж, тут Валексей нам мозги запудрил ))) Вот оригинальный текст:
Во-первых не всего лишь. Это означает что цикл For из Ады бесполезен без её системы типов. А система типов в Аде по сложности тянет поболее чем на 16 страниц :-)

Во-вторых ты проигнорировал второй мой пример. Эти примеры НЕ идентичны.

Второй пример -- это вот этот?
for Count in My_Array_Var'Range loop
    ...
end loop;
Так это по сути тоже самое, просто здесь мы явно указываем, что нам нужен диапазон индексов массива, а в случае с подтипом целого типа компилятор сам выводит, что нам нужен диапазон этого подтипа. Особой разницы нет -- и там и там диапазоны чисел...
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: valexey_u от Ноябрь 26, 2013, 08:35:48 pm

Да уж, тут Валексей нам мозги запудрил ))) Вот оригинальный текст:
Во-первых не всего лишь. Это означает что цикл For из Ады бесполезен без её системы типов. А система типов в Аде по сложности тянет поболее чем на 16 страниц :-)

Во-вторых ты проигнорировал второй мой пример. Эти примеры НЕ идентичны.

Второй пример -- это вот этот?
for Count in My_Array_Var'Range loop
    ...
end loop;
Так это по сути тоже самое, просто здесь мы явно указываем, что нам нужен диапазон индексов массива, а в случае с подтипом целого типа компилятор сам выводит, что нам нужен диапазон этого подтипа. Особой разницы нет -- и там и там диапазоны чисел...
Нет, разница есть. Массивы в Аде могут быть длины неизвестной на этапе компиляции.
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: Geniepro от Ноябрь 26, 2013, 08:39:52 pm
Разве в Аде есть форыч?   ???

Кстати, в той же вики пишется:
Цитата: http://en.wikipedia.org/wiki/Foreach_loop#Ada
Ada 2012 has generalized loops to foreach loops on any kind of container (array, lists, maps...):
for Obj of X loop
   -- Work on Obj
end loop;
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: valexey_u от Ноябрь 26, 2013, 08:46:32 pm
Разве в Аде есть форыч?   ???

Кстати, в той же вики пишется:
Цитата: http://en.wikipedia.org/wiki/Foreach_loop#Ada
Ada 2012 has generalized loops to foreach loops on any kind of container (array, lists, maps...):
for Obj of X loop
   -- Work on Obj
end loop;

Ну дык описанные мною выше конструкции - это по сути форыч образца 1983 года, тогда это представлялось вот так. Еще не было понимания как именно следует делать форыч, но было уже ясно что форыч штука много более правильная и безопасная для множества применений (но не для всех конечно, поэтому там есть и другие виды циклов), нежели обычный фор из паскаля, фортрана, или тем более while. Теперь же наконец выкатили уже современный, зрелый вариант.
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: Geniepro от Ноябрь 27, 2013, 07:15:07 am
Ну дык описанные мною выше конструкции - это по сути форыч образца 1983 года, тогда это представлялось вот так. Еще не было понимания как именно следует делать форыч, но было уже ясно что форыч штука много более правильная и безопасная для множества применений (но не для всех конечно, поэтому там есть и другие виды циклов), нежели обычный фор из паскаля, фортрана, или тем более while. Теперь же наконец выкатили уже современный, зрелый вариант.

for с итератором был ещё в языке CLU 1974 г.:
Цитата: http://ru.wikipedia.org/wiki/Клу
Итераторы

Одной из ключевых новаций языка стало введение абстракции управления — итератора. Идея итератора в том, чтобы обеспечить обобщённую реализацию доступа к элементам абстрактного типа данных вне зависимости от его параметризации и реализации. Реализация итератора полиморфного списка:
elems = iter (l:cvt) yields (t)
         for elt:t in rep$elements(l) do
           yield (elt)
         end
        end elems
Вызов такого итератора:
for i:int in lint$elems(l) do
  writeint (i)
end
Применение итератора позволяет избегать использование явных счётчиков цикла в условиях, когда заранее неизвестна конкретная реализация типа данных.
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: ddn от Декабрь 03, 2013, 05:38:48 am
Думал вбросить это еще в теме "форыч зло" http://oberspace.dyndns.org/index.php/topic,591.0.html, но там был уклон в структурность continue-break в циклах. А здесь будет самое то.



Оператор FOR зло уже потому что модифицирует пространство имен, превращая свой счетчик из VAR-переменной в IN-переменную в своем операторном параметре StatementSeq (даже при вызове в StatementSeq других процедур, счетчик не должен менятся), а после вызова FOR-оператора значение счетчика не определено языком и как бы не имеет права использоваться. А хороший оператор не должен никак менять пространство имен, и зря Вирт вернул этот нехороший FOR в Оберон-07. Поэтому у меня давно есть решение: FOR если и можно оставить, то только как спецпроцедуру, в чьем пространстве имен декларируется одно имя read only целого типа (а не импортируется как сейчас), а остальные идентификаторы globalIdent`i (i=1..N) импортируются в операторное тело StatementSeq как обычно (глобально).

То есть прежний вызов оператора FOR
ForStatement =
FOR ident ":=" Expr1 TO Expr2 [BY ConstExpr] DO
StatementSeq <* "(" ident {"," globalIdent`i} ")" *>
END.
превращается теперь в спецдекларацию процедуры identForProc:
ForProcDecl =
PROCEDURE identForProc FOR ident ":" identType [BY ConstExpr] DO
StatementSeq <* "(" ident {"," globalIdent`i} ")" *>
END identForProc.
а вызывается как обычная процедура:
identForProc(Expr1, Expr2 (* : <= identType *))где идентификатор identType - целый тип.
Хотя под вызовы FOR с разными (ident, ConstExpr, StatementSeq) придется декларировать как отдельные процедуры, но это будет правильно.

Делать ConstExpr внешним фактическим параметром, подобно Expr1 и Expr2, не следует, так как в Паскаль-языках нет объявления процедур с константными фактическими параметрами (будет нестандартная сигнатура), и как фактический параметр ConstExpr не мог бы тогда опускаться, подразумевая стандартное значение 1, а его значение 0 не давало бы ошибку при компиляции.
Но при желании, выражения Expr1 и Expr2, служащие фактическими безымянными параметрами, также можно убрать в декларацию:
PROCEDURE identForProc FOR<*IN*> ident ":" identType "=" Expr1 TO Expr2 [BY ConstExpr] DO
StatementSeq <* "(" ident {, globalIdent`i} ")" *>
END identForProc
Будет процедура без фактических параметров:
identForProc()

Помимо синтаксиса декларации, отличие FOR-процедуры от обычной процедуры состоит в многократном выполнении операторного тела StatementSeq при каждом вызове FOR-процедуры. При этом IN-переменная-счетчик ident в начале вызова инициируется значением Expr1, а между повторными выполнениями тела процедуры значение счетчика приращается на константную величину ConstExpr либо 1.

Все это можно описать и с помощью обычных процедур:
CONST
h = ConstExpr;
Check = 1 DIV h; (* h # 0 *)
...
PROCEDURE identForProc ((*IN*) i0, i1: identType);

VAR ident: identType;

PROCEDURE Stats (IN i: LONGINT);
BEGIN
StatementSeq (* (i, ... (* без h, i0 и i1 *)) *)
END;

BEGIN
ident := i0;
IF h>0 THEN
WHILE ident <= i1 DO
Stats(ident);
INC(ident, h)
END
ELSE
WHILE ident >= i1 DO
Stats(ident);
INC(ident, h)
END
END
END identForProc;
...
identForProc(Expr1, Expr2);
Приходиться делать два уровня вложенности, один для локальной переменной-счетчика, а второй для фиксации ее значения. Довольно громозко, и корректность конструкции должен проверять программист. Но поскольку, кроме Expr1, Expr2, ConstExpr и StatementSeq, прочее содержимое конструкции одинаково для всех FOR-процедур, то эти декларации можно сократить до предложеннего мною варианта спецпроцедуры.



Поскольку старый оператор FOR импортировал только те имена, что имеются в области видимости его вызова, вызов FOR-процедуры также можно разрешить только в той области видимости, где задекларирована сама эта FOR-процедура, т.е. идентификатор identForProc FOR-процедуры не должен экспортироваться во вложенные области видимости. Тогда мы получим почти аналог INLINE. Любой вызов FOR-процедуры можно будет заменить обратно на оператор FOR. При этом правда потребуется декларацию процедуры заменить на декларацию переменной-счетчика, и для каждого вызова FOR-оператора переменная-счетчик должна быть взята своя. Чистый INLINE был бы, если бы процедура не объявляла внутри себя никаких идентификаторов (кроме других вложенных INLINE процедур) и не имела бы именованных параметров (тогда ее декларация при INLINE просто отбрасывается), опять же при условии что вызовы такой процедуры идут только в той области видимости, где она была продекларирована.

Это условие необходимо хотя бы потому, что еще нужно учесть случай вложенных FOR-операторов. Ведь их операторные параметры StatementSeq имеют совпадающие области видимости за исключением того, что счетчик вложенного FOR как бы не виден в объемлющем его FOR (за вычетом области вложенного FOR). Значит FOR-процедуры, заменяющие эти вложенные операторы, дожны быть продекларированы внутри той же области видимости, но аналогично вложенными одна в другую. Декларативную область FOR-процедур для учета этой вложенности следует дополнить процедурным сектором для FOR-подпроцедур:

ForProcDecl =
PROCEDURE identForProc FOR ident ":" identType [BY ConstExpr]
{";" ForProcDecl`i}
DO
StatementSeq <* "(" ident {"," identForProc`i} {"," globalIdent`j} ")" *>
END identForProc.


У хорошего оператора должны быть только три синтаксических вида параметров: Designator, Expression и Statement (StatementSeq). Переменная-счетчик FOR-оператора теоретически тоже может быть любым составным именем, т.е. компонентой переменной, даже динамической, и даже импортироваться из другого модуля, но тогда ее изменения трудно контролировать. Поэтому счетчик FOR-оператора сделан строго ident. Я считаю, что таким (по синтаксису) параметрам место только в декларативной области.
Даже ConstExpression параметры в операторах идеологически подозрительны. Кроме FOR-оператора (необязательная секция BY), они были еще только в метках оператора CASE. Но уже в 07 версии Вирт их выпилил, заменив правда на более худший (усеченный) вариант: label = integer | string | ident. ConstExpression тоже должны быть только в декларациях.
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: vlad от Декабрь 03, 2013, 06:26:51 am
А здесь будет самое то.

А можно пример (кода) того, что получится в итоге?
А заводить переменную цикла тут же в FOR будет не проще, не?
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: ddn от Декабрь 03, 2013, 11:14:14 am
А можно пример (кода) того, что получится в итоге?
Вот например функция, вычисляющая детерминант матрицы:
PROCEDURE Det (IN A: ARRAY OF ARRAY OF REAL; (*IN*) n: INTEGER): REAL;
VAR
b: POINTER TO ARRAY OF BOOLEAN;
C: POINTER TO ARRAY OF ARRAY OF REAL;
d: REAL;
i, j, k, l: INTEGER;
BEGIN
ASSERT((LEN(A, 0) <= n) & (LEN(A, 1) <= n));
NEW(b, n); (* b[i] = FALSE *)
NEW(C, n, n);
FOR i := 0 TO n - 1 DO
FOR j := 0 TO n - 1 DO
C[i, j] := A[i, j]
END
END;
d := 1;
j := 0;
WHILE j < n DO
i := 0;
WHILE (i < n) & (b[i] OR (C[i, j] = 0)) DO
i := i + 1
END;
IF i = n THEN (* EXITIF.EXITWHILE *)
d := 0;
j := n - 1
ELSE (* ~b[i] & (C[i, j] # 0) *)
d := d * C[i, j];
(* C     b       j        l    *)
(* i:  FALSE  C[i, j]  C[i, l] *)
(* k:  FALSE  C[k, j]  C[k, l] *)
b[i] := TRUE;
FOR k := 0 TO n - 1 DO
IF ~b[k] THEN
FOR l := j + 1 TO n - 1 DO
C[k, l] := C[k, l] - C[k, j] * C[i, l] / C[i, j]
END
END
END;
FOR k := i + 1 TO n - 1 DO
IF ~b[k] THEN
C[k, j] := 0
END
END
(* C     b       j                       l                   *)
(* i:  TRUE   C[i, j]                 C[i, l]                *)
(* k:  FALSE     0     C[k, l] - C[k, j] * C[i, l] / C[i, j] *)
END;
INC(j)
END;
C := NIL;
b := NIL
;RETURN
d
END Det;
В ней 5 операторов FOR, причем две пары вложенных.

Поместив ее в модуль, можно проверить:
MODULE det;
IMPORT StdLog;
VAR a: ARRAY 2 OF ARRAY 2 OF REAL;
...
BEGIN
a[0, 0] := 3; a[0, 1] := 7;
a[1, 0] := 5; a[1, 1] := 11;
StdLog.Real(Det(a, 2)); (* -2.0 *)
a[0, 0] := 5; a[0, 1] := 5;
a[1, 0] := 9; a[1, 1] := 9;
StdLog.Real(Det(a, 2))  (*  0.0 *)
END det.

В результате замены операторов FOR на процедуры получим:
PROCEDURE Det (IN A: ARRAY OF ARRAY OF REAL; (*IN*) n: INTEGER): REAL;
VAR
b: POINTER TO ARRAY OF BOOLEAN;
C: POINTER TO ARRAY OF ARRAY OF REAL;
d: REAL;
i, j: INTEGER;

PROCEDURE For1 FOR i : INTEGER;
PROCEDURE For4 FOR j : INTEGER DO
C[i, j] := A[i, j]
END
DO
For4(0, n - 1)
END;

(* FOR i := 0 TO n - 1 DO
FOR j := 0 TO n - 1 DO
C[i, j] := A[i, j]
END
END;

For1(0, n - 1); *)

PROCEDURE For2 FOR k : INTEGER;
PROCEDURE For5 FOR l : INTEGER DO
C[k, l] := C[k, l] - C[k, j] * C[i, l] / C[i, j]
END
DO
IF ~b[k] THEN
For5(j + 1, n - 1)
END
END;

(* FOR k := 0 TO n - 1 DO
IF ~b[k] THEN
FOR l := j + 1 TO n - 1 DO
C[k, l] := C[k, l] - C[k, j] * C[i, l] / C[i, j]
END
END
END;

For2(0, n - 1); *)

PROCEDURE For3 FOR k : INTEGER DO
IF ~b[k] THEN
C[k, j] := 0
END
END;

(* FOR k := i + 1 TO n - 1 DO
IF ~b[k] THEN
C[k, j] := 0
END
END;

For3(i + 1, n - 1); *)

BEGIN
ASSERT((LEN(A, 0) <= n) & (LEN(A, 1) <= n));
NEW(b, n); (* b[i] = FALSE *)
NEW(C, n, n);
For1(1, n);
d := 1;
j := 0;
WHILE j < n DO
i := 0;
WHILE (i < n) & (b[i] OR (C[i, j] = 0)) DO
i := i + 1
END;
IF i = n THEN (* EXITIF.EXITWHILE *)
d := 0;
j := n - 1
ELSE (* ~b[i] & (C[i, j] # 0) *)
d := d * C[i, j];
(* C     b       j        l    *)
(* i:  FALSE  C[i, j]  C[i, l] *)
(* k:  FALSE  C[k, j]  C[k, l] *)
b[i] := TRUE;
For2(0, n - 1);
For3(i + 1, n - 1)
(* C     b       j                       l                   *)
(* i:  TRUE   C[i, j]                 C[i, l]                *)
(* k:  FALSE     0     C[k, l] - C[k, j] * C[i, l] / C[i, j] *)
END;
INC(j)
END;
C := NIL;
b := NIL
RETURN
d
END Det;
Если это покажется слишком сложным или трудным для восприятия, то FOR нужно выпилить вообще. Либо так, либо никак.


А заводить переменную цикла тут же в FOR будет не проще, не?
Будет методологически неправильней. Почему в операторном теле процедуры должны быть какие-то декларации?
В паскалевских ЯП декларативная область отделена от операторной. Иначе мы получим язык Дейкстры, где у каждого вызываемого оператора свое пространство имен. Операторы не должны вводить новых сущностей или менять свойства уже существующих, их дело работать с тем что уже есть. А если в теле процедуры в одном месте действуют одни сущности, в другом другие, или одна и та же используется с разным смыслом в разных местах, то это основание, чтобы вывести такие участки в подпроцедуры.
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: Wlad от Декабрь 03, 2013, 12:57:06 pm
... где у каждого вызываемого оператора свое пространство имен. Операторы не должны вводить новых сущностей или менять свойства уже существующих, их дело работать с тем что уже есть. А если в теле процедуры в одном месте действуют одни сущности, в другом другие, или одна и та же используется с разным смыслом в разных местах, то это основание, чтобы вывести такие участки в подпроцедуры.
Зависит. :)
Не надо однозначных оценок на уровне деклараций по организационным аспектам. Из каждого правила есть исключение (а есть области, где как раз одни исключения и работают :) ). Особенно, если затрагивается субъективное и неосмысливаемое на первый взгляд...

По рассматриваемому:
Или - настройка опций компилятора.
Или - работа внешней диагностики статических аспектов кода.
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: vlad от Декабрь 03, 2013, 03:58:46 pm
В результате замены операторов FOR на процедуры получим:

Для меня это выглядит как искусственное дробление единого контекста. И это все ради пространств имен и прочей методологии?

А заводить переменную цикла тут же в FOR будет не проще, не?
Будет методологически неправильней. Почему в операторном теле процедуры должны быть какие-то декларации?

А почему нет?

В паскалевских ЯП декларативная область отделена от операторной. Иначе мы получим язык Дейкстры, где у каждого вызываемого оператора свое пространство имен. Операторы не должны вводить новых сущностей или менять свойства уже существующих, их дело работать с тем что уже есть.

Почему? Особенно если речь идет о локальных переменных. Которые по сути своей - регистры для временных значений, не несущие никакой декларативной нагрузки.

А если в теле процедуры в одном месте действуют одни сущности, в другом другие, или одна и та же используется с разным смыслом в разных местах, то это основание, чтобы вывести такие участки в подпроцедуры.

Не-не. Не передергивай. С сущностями все хорошо, они одни и те же и с одним смыслом. Речь идет лишь о пространстве имен отдельного оператора - почему это плохо я не понял.
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: ddn от Декабрь 06, 2013, 10:56:25 am
В результате замены операторов FOR на процедуры получим:
Для меня это выглядит как искусственное дробление единого контекста. И это все ради пространств имен и прочей методологии?
Да!

А заводить переменную цикла тут же в FOR будет не проще, не?
Будет методологически неправильней. Почему в операторном теле процедуры должны быть какие-то декларации?
А почему нет?
Потому что в паскалях так принято.

В паскалевских ЯП декларативная область отделена от операторной. Иначе мы получим язык Дейкстры, где у каждого вызываемого оператора свое пространство имен. Операторы не должны вводить новых сущностей или менять свойства уже существующих, их дело работать с тем что уже есть.
Почему? Особенно если речь идет о локальных переменных. Которые по сути своей - регистры для временных значений, не несущие никакой декларативной нагрузки.
Любые переменные в паскалях объявляются, то есть имеют декларативную нагрузку. Но дело здесь не в этом, счетчик FOR тоже объявляется, в самом FOR или вне его. Локальные переменные объявляются во вложенной (локальной) области видимости, но тоже в ее декларативной части. Не следует объявлять идентификаторы в операторах.
Скрытые регистры присутствуют в операторах и выражениях, но они всегда безымянные.

А если в теле процедуры в одном месте действуют одни сущности, в другом другие, или одна и та же используется с разным смыслом в разных местах, то это основание, чтобы вывести такие участки в подпроцедуры.
Не-не. Не передергивай. С сущностями все хорошо
Сущность в данном случае, это идентификатор-счетчик который в операторе FOR либо вводиться, либо меняется с var на read only.
они одни и те же и с одним смыслом.
А какой смысл имеет счетчик вне FOR? Либо никакого, либо использется для других целей.
Речь идет лишь о пространстве имен отдельного оператора - почему это плохо я не понял.
Потому что в паскалях не принято делать пространства имен для отдельного (вызова) оператора. Все объявления идут перед началом операторного тела процедуры, модуля или программы.



http://46.254.16.186/oberon@conference.jabber.ru/2013/12/03.html
Цитировать
[19:38:03] <vlad2> Мне кажется товарищ ddn из лагеря драконоидов...
Почему драконоид? Я обычный паскалист.
Цитировать
[19:39:29] <vlad2> Вот я помню в универе писал вычисление детерминанта и не помню, чтоб там было 5 вложенных циклов...
И еще два WHILE. Эту функцию за 10 минут я переписал с ее версии под Мапл. Там нет 5 вложенных друг в друга FOR. Там две пары FOR, где в каждой паре FORы вложены.
Причем одна пара вложенных FOR используется для предварительной перезаписи матрицы в локальную матричную переменную, чтобы не изменять внешний параметр. Максимальня глубина вложенности там 3, что логично, так как метод Гаусса имеет сложность O(n^3) умножений. Алгоритм можно упростить (ценой лишних присваиваний) и убрать одиночный FOR.
Цитировать
[19:47:02] <alexey.veselovsky> не, ну ведь он говорит наоборот - плохо если FOR меняет область видимости
[19:47:08] <alexey.veselovsky> а он, в Обероне, НЕ МЕНЯЕТ!
И это ошибочая реализация логики FOR оператора. Что останется от специфики FOR, если в его теле значение счетчика будет коверкаться как угодно? Но модифицировать область видимости, вводя локальную IN-переменную или запрещая меняться внешней (по отношению к FOR) переменной, тоже нельзя, это нарушение паскалевской методологии. Значит или переводить FOR в процедурную форму, или полностью изгнать с позором этот рассадник греха и порока из райских кущь Оберона.
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: Geniepro от Декабрь 06, 2013, 11:19:51 am
И это ошибочая реализация логики FOR оператора. Что останется от специфики FOR, если в его теле значение счетчика будет коверкаться как угодно? Но модифицировать область видимости, вводя локальную IN-переменную или запрещая меняться внешней (по отношению к FOR) переменной, тоже нельзя, это нарушение паскалевской методологии. Значит или переводить FOR в процедурную форму, или полностью изгнать с позором этот рассадник греха и порока из райских кущь Оберона.

Однозначно изгнать! Вместе с расширяемыми записями, ведь их в паскале тоже не было!
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: valexey_u от Декабрь 06, 2013, 11:37:37 am
И это ошибочая реализация логики FOR оператора. Что останется от специфики FOR, если в его теле значение счетчика будет коверкаться как угодно? Но модифицировать область видимости, вводя локальную IN-переменную или запрещая меняться внешней (по отношению к FOR) переменной, тоже нельзя, это нарушение паскалевской методологии. Значит или переводить FOR в процедурную форму, или полностью изгнать с позором этот рассадник греха и порока из райских кущь Оберона.

Однозначно изгнать! Вместе с расширяемыми записями, ведь их в паскале тоже не было!
И сборщик мусора пусть с собою прихватят!
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: ddn от Декабрь 06, 2013, 12:09:45 pm
http://oberspace.dyndns.org/index.php/topic,593.msg20090.html
NEW(C, n, n);
For1(1, n);
Здесь, в варианте функции с FOR процедурами, у меня ошибка.

Должно быть:
NEW(C, n, n);
For1(0, n - 1);
Название: Re: [Oberon 07/13] Семантика FOR
Отправлено: vlad от Декабрь 06, 2013, 03:48:43 pm
Для меня это выглядит как искусственное дробление единого контекста. И это все ради пространств имен и прочей методологии?
Да!

Это очень настораживает.

Потому что в паскалях так принято.

А это подтверждает опасения: http://pritchi.livejournal.com/92886.html
У нас тут главное отличие от оберонкора вовсе не в матюгах, а в том, что критической проверке подвергается все, даже то, что сам сам Вирт назвал правильным. И не ради критики, а ради поиска лучшего.

Возвращаясь к нашим баранам. Зачем иметь локальные переменные в отдельной декларативной части? Есть какие-нибудь формальные причины, кроме "здесь так заведено"?

Цитировать
[19:38:03] <vlad2> Мне кажется товарищ ddn из лагеря драконоидов...
Почему драконоид? Я обычный паскалист.

У драконоидов обычно сильно смещенное восприятие программерской реальности. Из-за этого порой очень трудно понять суть описываемых ими проблем и их возможное решение.

P.S. Про "райские кущи" - зачет, понравилось :)