OberonCore https://forum.oberoncore.ru/ |
|
Обобщенный цикл https://forum.oberoncore.ru/viewtopic.php?f=86&t=3159 |
Страница 1 из 2 |
Автор: | Peter Almazov [ Суббота, 15 Январь, 2011 07:29 ] |
Заголовок сообщения: | Обобщенный цикл |
Я давно собирался написать статью по этому вопросу, да как-то все руки не доходят. Но, поскольку здесь viewtopic.php?f=27&t=3157&start=40 в очередной раз разгорелся базар по этому поводу, то напишу кое-какие тезисы. Итак, имеем обобщенный цикл вида Код: цикл Середину с выходом можно гонять как слайдер вверх-вниз и получать граничные случаи: цикл while и цикл repeat..until. Это хорошо.последовательность команд Х что-нибудь типа exit или break по условию последовательность команд Y конец цикла Плохо то, что формальный аппарат, описанный у Дейкстры-Грисса можно применять вроде бы только для циклов типа while. В принципе, Кнут приводит аксиоматизацию Дала для обобщенного цикла: Цитата: Пусть: {P}S{Q} {Q & B}T{P} В ней нет ничего сложного, но для простого программиста польза от этой записи равна строго нулю. Тогда: {P} loop: S; while B : T; repeat; {Q & ~B } (стр. 49) Тем не менее, все не так плохо. Надо только ответить на 2 вопроса. 1. Что является телом обобщенного цикла? 2. В какой точке цикла нужно проверять инвариант цикла? Ответить на эти вопросы проще, чем их поставить. Если немного подумать, то легко понять, что телом цикла является кусок Y;X. Т.е., чтобы рассуждать о таком цикле, нужно просто мысленно подставить вехний кусок X под нижний Y. А вся конструкция эквивалентна последовательности Код: X; Здесь как раз и вылезает то самое дублирование кода.пока условие цикл Y; X; конец цикла Что касается инварианта цикла, которой традиционно проверяется "перед циклом", то уже становится ясно, что в данном случае инвариант нужно проверять внутри цикла, в точке перед условием выхода. Вот и все. Все наработки для циклов while остаются в силе (в том числе и весь бред про линейный поиск, для любителей). В заключение надо отметить, что с эстетической точки зрения цикл с выходом из середины выглядит, конечно, отвратно. И вреден для неокрепших умов. Здесь - самое главное иметь четкую картину в голове. И укреплять ум(ы) . |
Автор: | Илья Ермаков [ Суббота, 15 Январь, 2011 19:43 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Спасибо, очень интересная заметка. === Peter Almazov писал(а): В заключение надо отметить, что с эстетической точки зрения цикл с выходом из середины выглядит, конечно, отвратно. И вреден для неокрепших умов. Здесь - самое главное иметь четкую картину в голове. И креплять ум(ы) . Однако, имеются серьёзные основания думать, что все "хорошо-плохо", применимые для "неокрепших умов", полезно сохранять и для самой-самой крутой профессиональной деятельности. === По поводу применимости: возможно, это полезно в случаях, когда повторяемый кусок большой, а есть причины не выносить его во вложенную процедуру. Вот, кстати, как раз в языках без вложенных процедур ? ... |
Автор: | Peter Almazov [ Суббота, 15 Январь, 2011 19:52 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Илья Ермаков писал(а): Peter Almazov писал(а): И креплять ум(ы) . |
Автор: | Geniepro [ Суббота, 15 Январь, 2011 19:56 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Peter Almazov писал(а): В заключение надо отметить, что с эстетической точки зрения цикл с выходом из середины выглядит, конечно, отвратно. И вреден для неокрепших умов. Здесь - самое главное иметь четкую картину в голове. И укреплять ум(ы) . Это решается привычкой, то есть воспитанием. |
Автор: | ==== [ Суббота, 15 Январь, 2011 20:01 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
. |
Автор: | Geniepro [ Суббота, 15 Январь, 2011 20:02 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Илья Ермаков писал(а): По поводу применимости: возможно, это полезно в случаях, когда повторяемый кусок большой, а есть причины не выносить его во вложенную процедуру. Вот, кстати, как раз в языках без вложенных процедур ? ... Вложенные процедуры не всегда удобны и к месту выглядят. Например, в сях их вообще нет. В С#, правда, их можно делать по месту надобности лямбдами, то есть уже почти на уровне Хаскелла/Окамла. В паскалевом семействе вложенные процедуры приходится делать чёрти где от того места, где нужно их тело, то есть при создании и изучении такой процедуры приходится сбивать контекст -- смотреть вверх-вниз. Неудобно. |
Автор: | Илья Ермаков [ Суббота, 15 Январь, 2011 20:03 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Цитата: Илья Ермаков писал(а): Однако, имеются серьёзные основания думать, что все "хорошо-плохо", применимые для "неокрепших умов", полезно сохранять и для самой-самой крутой профессиональной деятельности. Илья, у вас стал проявляться прогресс.В чём прогресс? Я всегда считал, что рост профессионального уровня не является причиной для ослабления жесткой дисциплины, которая вводится для начинающих. Жёсткость рамок должна сохраняться навсегда. |
Автор: | Alexey Veselovsky [ Суббота, 15 Январь, 2011 20:22 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Geniepro писал(а): Илья Ермаков писал(а): По поводу применимости: возможно, это полезно в случаях, когда повторяемый кусок большой, а есть причины не выносить его во вложенную процедуру. Вот, кстати, как раз в языках без вложенных процедур ? ... Вложенные процедуры не всегда удобны и к месту выглядят. Например, в сях их вообще нет. В С#, правда, их можно делать по месту надобности лямбдами, то есть уже почти на уровне Хаскелла/Окамла. http://valexey.blogspot.com/2009/09/blog-post_07.html Geniepro писал(а): В паскалевом семействе вложенные процедуры приходится делать чёрти где от того места, где нужно их тело, то есть при создании и изучении такой процедуры приходится сбивать контекст -- смотреть вверх-вниз. Неудобно. На это принято отвечать, мол нефиг писать функции которые не умещаются на одном экране |
Автор: | Peter Almazov [ Суббота, 15 Январь, 2011 20:29 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Если речь идет о том, чтобы преобразовать цикл с выходом из середины к виду цикл while, то нужно использовать вложенную функцию, которая всегда будет иметь побочный эффект. А функции с побочным эффектом "дурно пахнут". |
Автор: | Илья Ермаков [ Суббота, 15 Январь, 2011 20:36 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Если функция локальная, то про "дурной запах" - просто предрассудок, имхо. Конечно, в эпоху модности ФП за это будут смотреть криво ) |
Автор: | Geniepro [ Суббота, 15 Январь, 2011 20:43 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Alexey Veselovsky писал(а): Geniepro писал(а): Вложенные процедуры не всегда удобны и к месту выглядят. Например, в сях их вообще нет. В С#, правда, их можно делать по месту надобности лямбдами, то есть уже почти на уровне Хаскелла/Окамла. http://valexey.blogspot.com/2009/09/blog-post_07.html А вариант, приведённый Вами в статье, -- это всё равно что чесать левой ногой правое ухо. Затуманивание смысла... |
Автор: | Alexey Veselovsky [ Суббота, 15 Январь, 2011 20:43 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Илья Ермаков писал(а): Если функция локальная, то про "дурной запах" - просто предрассудок, имхо. Конечно, в эпоху модности ФП за это будут смотреть криво ) Если в монаде IO, то нормально Ну или в ST. |
Автор: | Alexey Veselovsky [ Суббота, 15 Январь, 2011 20:45 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Geniepro писал(а): Про C++ я и не упоминал. Там вроде тоже можно лямбды делать, делегатами симитировать. А вариант, приведённый Вами в статье, -- это всё равно что чесать левой ногой правое ухо. Затуманивание смысла... А по моему, всё как раз там получается однозначно и очевидно. Вот эти переменные у нас могут меняться локальными функциями, а вот эти нет. Соответственно локальные функции зависят от этих и этих переменных. Удобно для рефакторинга. Сразу видно что и где. По сути, явно огороженное замыкание получается. |
Автор: | Geniepro [ Суббота, 15 Январь, 2011 20:46 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Alexey Veselovsky писал(а): Если в монаде IO, то нормально Ну или в ST. У монад IO/ST суть не в том, что они разрешают побочные эффекты, а в том, что они их строго локализуют. То есть дают на ними, эффектами этими побочными, строгий контроль. |
Автор: | Alexey Veselovsky [ Суббота, 15 Январь, 2011 20:47 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Geniepro писал(а): Alexey Veselovsky писал(а): Если в монаде IO, то нормально Ну или в ST. У монад IO/ST суть не в том, что они разрешают побочные эффекты, а в том, что они их строго локализуют. То есть дают на ними, эффектами этими побочными, строгий контроль. Именно потому я и сказал, что нормально в них |
Автор: | Geniepro [ Суббота, 15 Январь, 2011 20:47 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Alexey Veselovsky писал(а): А по моему, всё как раз там получается однозначно и очевидно. Вот эти переменные у нас могут меняться локальными функциями, а вот эти нет. Соответственно локальные функции зависят от этих и этих переменных. Удобно для рефакторинга. Сразу видно что и где. По сути, явно огороженное замыкание получается. Ну вообще интересно, надо подумать, попробовать... |
Автор: | Илья Ермаков [ Понедельник, 31 Январь, 2011 10:22 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Есть предложение ещё более общего цикла. Который бы как раз покрыл вариант Петра и ещё случай, разбиравшийся в теме viewtopic.php?f=27&t=3175 "AND THEN". И был бы в языке вместо LOOP. Мне кажется, Info21 даже предлагал такое что-то, но если вру, прошу извинить. Проблема, которую решают иногда с помощью LOOP, как известно, в том, что между конъюнктами условия цикла надо бы что-то сложное вычислять. Цикл Петра как раз позволяет вычислять вообще перед всем условием, избегая дублирования и перенося такие вычисления из конца тела в более естественное место в начало. Но иногда надо действовать между конъюнктами. Код: LOOP ... ; ... ; CHECK Conjunct1 DO ...; ... ; CHECK Conjunct2 DO ...; ... ; END В случае истинности конъюнкта выполнение проходит в следующую секцию цикла, уже под охраной условия конъюнкта. В случае ложности, разумеется, цикл завершается. Условие цикла и его отрицание легко собирается в уме. В Аде есть такой цикл с exit when, но нужно, чтобы было именно условие продолжения, для грамотного построения цикла думать через него удобнее. И строить цикл почти как обычный WHILE, но с промежуточными вычислениями. В случае exit when программист вынужден думать наоборот, "через одно место": "а когда же мне спрыгнуть с цикла". Ситуация из обсуждавшейся темы с цепочкой проверок и прерыванием решается с добавлением в конце CHECK FALSE DO END. Этап, на котором прервалось, отслеживаем по спец. целой переменной. |
Автор: | Сергей Прохоренко [ Понедельник, 31 Январь, 2011 11:21 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Предложенная Ильей Ермаковым конструкция обобщенного цикла добавлена в PureBuilder в несколько иной форме. |
Автор: | Info21 [ Понедельник, 31 Январь, 2011 12:02 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Илья Ермаков писал(а): Мне кажется, Info21 даже предлагал такое что-то, но если вру, прошу извинить. В точности это и предлагал modulo выбор ключевых слов.
|
Автор: | Peter Almazov [ Понедельник, 31 Январь, 2011 13:55 ] |
Заголовок сообщения: | Re: Обобщенный цикл |
Илья Ермаков писал(а): Есть предложение ещё более общего цикла. Который бы как раз покрыл вариант Петра и ещё случай, разбиравшийся в теме viewtopic.php?f=27&t=3175 "AND THEN". Я довольно скептически отнесся к той ветке и изобретенным там конструкциям.Но, могу заметить, что полный вариант статьи о циклах предусматривал также обсуждение циклов со многими выходами. Однако эта часть пока не созрела для изложения. |
Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |