OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Суббота, 20 Апрель, 2019 03:19

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




Начать новую тему Ответить на тему  [ Сообщений: 53 ]  На страницу Пред.  1, 2, 3  След.
Автор Сообщение
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 12:04 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9115
Откуда: Россия, Орёл
Vlad писал(а):
Сейчас тебя пошлют читать Дейкстру :) Забей. Типичный случай, когда break (в твоем случае EXIT) удобнее/нагляденее/эффективнее.

Чем
а) удобнее? на 3 удара по клавишам меньше?
б) чем нагляднее? Для меня нет ничего наглядного в цикле, на который я не вижу сразу пред-постусловий и инварианта. Я должен ломать голову, изображая из себя компьютер, чтобы понять, а так ли оно будет выполняться, как нужно... Вместо того, чтобы сразу видеть декларатив - а что оно делает.
в) Чем эффективнее?
Только не сравнивать с UNTIL с лишним IF - я этот вариант не рекомендовал тоже...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 12:04 
Администратор

Зарегистрирован: Вторник, 15 Ноябрь, 2005 01:14
Сообщения: 4255
Откуда: Россия, Орёл
Vlad писал(а):
PGR писал(а):
Почему GOTO? У этого цикла LOOP одна точка входа и одна точка выхода.


Сейчас тебя пошлют читать Дейкстру :)

...что несомненно очень полезно... :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 12:05 

Зарегистрирован: Понедельник, 29 Январь, 2007 19:00
Сообщения: 370
Откуда: Украина, Запорожье
Илья Ермаков писал(а):
Но вообще цикл LOOP позволяет делать сколько угодно точек выхода. Не стоит его использовать. Если конструкция позволяет делать много выходов, то тут же начнут делать - просто в силу правила "насыщения степеней свободы инструмента".

Мне кажется, что и нужно было в языке сделать LOOP только с одним выходом. А где в самом BlackBox используется LOOP с несколькими выходами?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 12:08 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9115
Откуда: Россия, Орёл
А какой смысл в LOOP с одним выходом? :-)
А где - да посмотрите Info->Search In Sources на слово LOOP - места 3-4 найдется...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 12:09 

Зарегистрирован: Понедельник, 29 Январь, 2007 19:00
Сообщения: 370
Откуда: Украина, Запорожье
А какой инвариант у цикла с использованием WHILE? Вы думаете он не будет выполняться у этого цикла LOOP?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 12:21 

Зарегистрирован: Понедельник, 29 Январь, 2007 19:00
Сообщения: 370
Откуда: Украина, Запорожье
Илья Ермаков писал(а):
А какой смысл в LOOP с одним выходом? :-)

Component Pascal Language Report писал(а):
Loop statements are useful to express repetitions with several exit points or cases where the exit condition is in the middle of the repeated statement sequence.


Илья Ермаков писал(а):
А где - да посмотрите Info->Search In Sources на слово LOOP - места 3-4 найдется...

9 модулей, а мест ещё больше :) В основном и используется LOOP с одним EXIT...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 12:26 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Илья Ермаков писал(а):
Вообще, полезно почитать книжку Бейбера "Программное обеспечение без ошибок".
viewtopic.php?t=411


Гы :) Кстати к вопросу о "первосортных" программистах, которые пишут "правильные" циклы для использования "второсортными". Я тут глянул реализацию стандартного сишного find. Ужасайтесь :)

Код:
{
  _STLP_DIFFERENCE_TYPE(_RandomAccessIter) __trip_count = (__last - __first) >> 2;

  for ( ; __trip_count > 0 ; --__trip_count) {
    if (*__first == __val) return __first;
    ++__first;

    if (*__first == __val) return __first;
    ++__first;

    if (*__first == __val) return __first;
    ++__first;

    if (*__first == __val) return __first;
    ++__first;
  }

  switch(__last - __first) {
  case 3:
    if (*__first == __val) return __first;
    ++__first;
  case 2:
    if (*__first == __val) return __first;
    ++__first;
  case 1:
    if (*__first == __val) return __first;
    ++__first;
  case 0:
  default:
    return __last;
  }
}


Тут вам и множественные return (даже не break) из цикла, и switch (о ужас!) без break'ов.

P.S. Только не надо кричать, что STLPort писали "второсортные" программисты. Скромнее надо быть (c).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 12:26 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9115
Откуда: Россия, Орёл
PGR писал(а):
А какой инвариант у цикла с использованием WHILE? Вы думаете он не будет выполняться у этого цикла LOOP?

Будет. Просто в общем случае неочевидно. Можно все, что угодно. Вопрос: зачем? :-)
Развели дискуссию в ветке для начинающих - развращаете малолетних :-) Что можно делать "в принципе", совсем не обязательно делать (и даже вообще знать) новичкам. Пусть руку набивают, пребывая в твердой (и для большинства случаев - правильной) уверенности, что есть только WHILE и FOR.. :-)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 12:38 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9115
Откуда: Россия, Орёл
Vlad писал(а):
Тут вам и множественные return (даже не break) из цикла, и switch (о ужас!) без break'ов.

P.S. Только не надо кричать, что STLPort писали "второсортные" программисты. Скромнее надо быть (c).

Не ужасает. Как раз пример куска кода (довольно низкоуровневого и нетривиального), где эти возможности полезны. Как раз то, про что я говорил - LOOP иногда полезен. С множественными EXIT. И RETURN изнутри цикла иногда полезен. (и, кстати, в КП такие EXIT и RETURN места всегда выделяются жирным, чтоб бросались в глаза).
Кстати, один раз из тех трех, когда я все-таки использовал LOOP, я сэмулировал на нем сишный case без break :-)

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 12:42 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Илья Ермаков писал(а):
удобнее/нагляденее/эффективнее.

Чем
а) удобнее? на 3 удара по клавишам меньше?
[/quote]

Не надо писать два раза одно и то же условие. У меня в таких случаях срабатывет "звоночек" не хуже твоего на break :)

Илья Ермаков писал(а):
б) чем нагляднее? Для меня нет ничего наглядного в цикле, на который я не вижу сразу пред-постусловий и инварианта.


Ты там чего-то говорил про "общепринятые схемы, которые сразу различимы в коде"? Так вот, вечный цикл с break'ом - типичная схема решения задачи последовательного чтения/проверки. Инвариант и пред/пост условия у него очевидны.

Илья Ермаков писал(а):
в) Чем эффективнее?
Только не сравнивать с UNTIL с лишним IF - я этот вариант не рекомендовал тоже...


Проверка может быть дорогой. Вызов "берем следующий" - нетривиальным. Можно отбиться временными переменными, но ради чего?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 12:50 

Зарегистрирован: Понедельник, 29 Январь, 2007 19:00
Сообщения: 370
Откуда: Украина, Запорожье
Илья Ермаков писал(а):
И RETURN изнутри цикла иногда полезен.

А вот таких случаев в самом BlackBox намного больше, чем циклов LOOP...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 12:58 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9115
Откуда: Россия, Орёл
Vlad писал(а):
Не надо писать два раза одно и то же условие. У меня в таких случаях срабатывет "звоночек" не хуже твоего на break :)

Где в варианте с WHILE лишнее условие? По поводу варианта с REPEAT я уже не раз сказал..
В варианте с WHILE лишний раз пишется операция взятия элемента. Все правильно и логично - эта операция выполняется на один раз больше, чем тело цикла. Прежде чем запустить цикл, мы выполняем инициализацию, становимся на исходную позицию, берем первый элемент...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 13:00 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9115
Откуда: Россия, Орёл
Vlad писал(а):
Вызов "берем следующий" - нетривиальным. Можно отбиться временными переменными, но ради чего?

Может быть нетривиальным. В таком случае он прото выносится в отдельную вложенную процедуру, а сам цикл остается красивым и очевидным:
Код:
Next;
WHILE взят DO
  ...
  Next
END


Последний раз редактировалось Илья Ермаков Четверг, 14 Июнь, 2007 13:04, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 13:03 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9115
Откуда: Россия, Орёл
PGR писал(а):
Илья Ермаков писал(а):
И RETURN изнутри цикла иногда полезен.

А вот таких случаев в самом BlackBox намного больше, чем циклов LOOP...

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 13:37 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Илья Ермаков писал(а):
Vlad писал(а):
Не надо писать два раза одно и то же условие. У меня в таких случаях срабатывет "звоночек" не хуже твоего на break :)

Где в варианте с WHILE лишнее условие?


Там лишнее чтение. Реакция такая же как на копипаст.

Илья Ермаков писал(а):
По поводу варианта с REPEAT я уже не раз сказал..
В варианте с WHILE лишний раз пишется операция взятия элемента. Все правильно и логично - эта операция выполняется на один раз больше, чем тело цикла. Прежде чем запустить цикл, мы выполняем инициализацию, становимся на исходную позицию, берем первый элемент...


Не вижу ничего логичного в том, что действие, ради которого заводится цикл, повторяется n + 1 раз.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 13:48 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Илья Ермаков писал(а):
Может быть нетривиальным. В таком случае он прото выносится в отдельную вложенную процедуру


Еще лучше. На что только люди не идут, чтобы break не писать...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 13:49 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9115
Откуда: Россия, Орёл
Vlad писал(а):
Не вижу ничего логичного в том, что действие, ради которого заводится цикл, повторяется n + 1 раз.

Действие, "ради которого заводится цикл" - полезное действие, "нагрузка" цикла - это подсчет числа элементов или другая более сложная операция С ТЕКУЩИМ СЧИТАННЫМ ЭЛЕМЕНТОМ. Сколько элементов, столько раз и должен выполниться цикл.
А чтение из файла - это всего лишь "обвязка", изменение контекста цикла. То, что в C++-ном for ты бы поставил в третьей секции его заголовка.
А до цикла - инициализация. В данном конкретном случае (полный проход по элементам потока) инициализация повторяет изменение. В другом случае - полный проход по связному списку или массиву - не совпадает:
Код:
i := list;
WHILE i # NIL DO
  ...
  i := i.next
END

Эти циклы ничем друг от друга не отличаются. Одна и та же схема - полный проход. На основе одинаковости в мелком частном случае двух по сути различных частей алгоритмической схемы стоит ли делать ее свертку? Вообще стоит ли тратить свое драгоценное внимание на это...
"Правило 1. Никогда не оптимизируйте.
Правило 2. Если вы все-таки решили оптимизировать, то см. правило 1."
(С) Кнут
:-)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 13:55 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9115
Откуда: Россия, Орёл
Vlad писал(а):
Илья Ермаков писал(а):
Может быть нетривиальным. В таком случае он прото выносится в отдельную вложенную процедуру


Еще лучше. На что только люди не идут, чтобы break не писать...

А что не нравится? :-) "Разделяй и властвуй". Если на то пошло - в сложном алгоритме я могу отдельно поменять структуру данных и метод сдвига к следующему элементу ("итератор") - и отдельно алгоритмическую логику. Прошу не развивать тему "а все потому, что у вас нет шаблонов" - это я так, к слову... И так ветка растет сегодня как на дрожжах :-)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 14:05 

Зарегистрирован: Понедельник, 29 Январь, 2007 19:00
Сообщения: 370
Откуда: Украина, Запорожье
Да, если хорошо подумать и учесть, что LOOP в КП слишком общий, то правильнее использовать WHILE.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 14:19 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Илья Ермаков писал(а):
А до цикла - инициализация. В данном конкретном случае (полный проход по элементам потока) инициализация повторяет изменение. В другом случае - полный проход по связному списку или массиву - не совпадает:


Это все схоластика и мне неинтересно в нее вдаваться. Конкретный код с break/return как минимум удобнее и нагляднее.


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

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


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

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


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

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2019, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB