Oberon space
General Category => Общий раздел => Тема начата: ilovb от Ноябрь 21, 2013, 03:15:52 pm
-
Я эволюционировал.
Предпосылки:
http://oberspace.dyndns.org/index.php/topic,225.msg6308.html#msg6308
http://oberspace.dyndns.org/index.php/topic,584.msg19744.html#msg19744
Сегодня два часа воевал с одним циклом.
Планирование производства.(распределение операций по исполнителям и по времени)
3 вложенных Форыча, ~300 строк, в каждом форыче несколько continue.
Мозг сломал, но так и не придумал как мне вклиниться в эту говнологику.
В итоге, сдавшись, стал размышлять о причинах этого безобразия. И пришел к выводу, что виновата комбинация лени и херового дизайна языка.
Все эти continue (кроме одного) возникли скорее всего не сразу.
Код эволюционировал со временем и условия втыкались автором "по месту", ибо это гораздо легче, чем реструктуризация цикла.
Причина, по которой цикл изначально писался через форыч+continue, тоже банальна.
Дизайн языка и коллекций провоцирует на использование таких циклов. Т.к. форыч интуитивно кажется проще и легче чем while, плюс коллекции спроектированы так, чтобы их удобно было обходить именно форычем.
В результате имеем форыч+continue там, где явно должен быть while.
Если есть возможность написать цикл через форыч, то этой возможностью обязательно воспользуются (с)
Вывод: Форыч зло.
-
Это смотря какой форыч :-) Вот std::for_each от этих недостатков свободен. Ну и вообще это не языковая конструкция :-)
Равно как и подобные штуки в том же Haskell'e. Там вообще в принципе циклов нема. А foreach есть. Но не в языке.
-
Да, кроме того, говнокод можно написать хоть с while хоть с форычем хоть с чем угодно. Тут не конструкции виноваты, а таки руки и голова писавшего. А скорее всего проблемы еще уровнем выше - работа организована не правильно, организация работы наверняка такова, что провоцирует на лепление заплаток на скорую руку, время на рефакторинг кода в план не заложено в принципе.
-
Вот std::for_each от этих недостатков свободен.
Ну это другое. Тема именно про цикл.
-
Да, кроме того, говнокод можно написать хоть с while хоть с форычем хоть с чем угодно.
С форычем его легче написать. А с while нужно таки немного включать мозг (иначе оно вообще работать не будет), и народ пытается его избегать где возможно.
ps Я подразумеваю while без continue и break.
-
Вот std::for_each от этих недостатков свободен.
Ну это другое. Тема именно про цикл.
for each - специализированный цикл. И в этом его достоинство. А то, что в него напихали continue (break?) или еще не знаю чего - это уже на совести авторов языка.
std::for_each использую практически каждый день, все хорошо.
P.S. Сам continue не использую.
-
ps Я подразумеваю while без continue и break.
Ха-ха-ха. Хитрый какой. Т.е., в for each мы будем пихать continue/break и смешивать его с говном, а священный while - надо писать только по всем правилам :)
-
Есть циклы которые нельзя написать через форыч без continue или break.
Речь именно о таких циклах. Их нужно писать через while, но народ этого не делает. Неужели непонятно из первого поста?
std::for_each использую практически каждый день, все хорошо.
Тема про цикл!
-
Есть циклы которые нельзя написать через форыч без continue или break.
Речь именно о таких циклах. Их нужно писать через while, но народ этого не делает. Неужели непонятно из первого поста?
Действительно было не понятно. С тем что делать абсолютно всё через for_each, или через while не правильно - конечно соглашусь. И да, в языке (если язык таков что без непосредственной поддержки циклов в языке там не обойтись) либо в стандартной либе (если язык высокоуровневый) должен быть набор узкоспециализированных "циклов", а не надобор универсального непонятночего.
-
Ну я не против форыча как такового. По сути, да, я против неправильного использования.
С этой проблемой можно бороться выпиливанием из языка continue и break.
Но мне думается, что лучше выпилить форыч (цикл). Так как он навязывается дизайном коллекций.(необходимости в нем нет) Дизайн ведь можно сделать удобным для while (курсоры) Форыч просто лишняя сущность.
Ну и функции типа std::for_each тоже его спокойно заменяют.
-
...
Сегодня два часа воевал с одним циклом.
...
3 вложенных Форыча, ~300 строк, в каждом форыче несколько continue.
...
Вывод: Форыч зло.
Вывод неверный. Зло -- не форыч, а эти самые триста строк говнологики в нём...
-
Кстати еще более проявлено навязывание форыча и continue с break в Python.
Хоть я и симпатизирую лаконичности этого языка, но дизайн циклов в нем будто бывалый говнокодер проектировал.
-
Вывод неверный. Зло -- не форыч, а эти самые триста строк говнологики в нём...
Под говнологикой подразумевался форыч+continue*n. Так что мимо...
-
Вывод неверный. Зло -- не форыч, а эти самые триста строк говнологики в нём...
Под говнологикой подразумевался форыч+continue*n. Так что мимо...
В любом случае цикл, в котором 300 строк, -- уже зло по умолчанию. А форыч он или while или std::for_each -- уже не важно.
-
Ну замени код на вызовы процедур. Сути это не меняет.
ps Если бы я не написал про 300 строк, что бы изменилось?
-
for(String str : StringList) {
....
if (str.equals("some")) continue;
...
}
Просто вместо continue нужно писать так:
for (String str : StringList) {
....
if (!str.equals("some")) {
...
}
}
PS. на Java
-
И чем это лучше continue?
-
Ну замени код на вызовы процедур. Сути это не меняет.
ps Если бы я не написал про 300 строк, что бы изменилось?
Изменился бы масштаб -- злом оказался бы тот программахер, что этот непонятный цикл наколбасил -- кода всего ничего, а хрен поймёшь...
-
И чем это лучше continue?
Более явно видны намерения программиста. continue/break можно и не разглядеть, а сдвиги кода вправо-влево указывают на изменение пути прохождения кода...
-
Ну замени код на вызовы процедур. Сути это не меняет.
ps Если бы я не написал про 300 строк, что бы изменилось?
Если бы там было 20 строк, и в этих 20 строках были собраны все эти условия с continue, то понять что там происходит было бы НАМНОГО проще.
-
Я наверно непонятно объясняюсь. ::) (пардонте если что)
Проблема в том, что такое:
i := 0;
while ~cond & (i < y.count) do
x := y[i]
...
INC(i);
end;
народ пишет так:
for x in y do
...
if cond then
continue;
end;
...
end;
-
Я так вообще практически не пишу continue.
break -- да, сколько угодно, а вот continue -- не, не слышал...
-
Тоже не пишу. Но в чужом коде постоянно вижу.
-
Думаю все же лучше без бреков и континьев (пардонте за мой хранцузкий), чем без форыча.
И да, согласен, что лучше обозначить континьюс условием, т.к. сразу видно, что код может не выполняться
-
По этому правильнее тема звучит так: континьюсы и брейки - зло :)
-
Еще правильнее так: континьюсы и брейки в форычах - зло.
Если написано "для каждого ... делай", а оно делается не для каждого, то это сознательное введение в заблуждение.
-
Еще правильнее так: континьюсы и брейки в форычах - зло.
Если написано "для каждого ... делай", а оно делается не для каждого, то это сознательное введение в заблуждение.
Ну а как? Иногда для простоты кода лучше сделать перебор через форыч, а прерывание перебора -- через брейк. Главное что бы код цикла был коротким -- тогда проблем с восприятием не возникнет...
-
Да, был бы составной цикл типа
foreach (var x in xs) while (condition) { statements }
цены бы ему не было бы...
-
Зло - это break в форыче, а continue (или IFы внутри цикла) позволяют выразить вполне определённый смысл:
для всех этаких сделать кой-чего.
-
Зло - это break в форыче, а continue (или IFы внутри цикла) позволяют выразить вполне определённый смысл:
для всех этаких сделать кой-чего.
Так continue как раз-таки пропускает итерацию цикла.
some_loop(...)
{
statement1;
if (condition) continue;
statement2;
}
эквивалентноsome_loop(...)
{
statement1;
if (!condition)
{
statement2;
}
}
Ну и зачем, спрашивается, нужен continue? Только для того, что бы уменьшить вложенность у statement2 (ценой ухудшения понятности кода)?
-
Вспоминается старый добрый FoxPro, у которого во всех циклах, включая аналог форыча SCAN были LOOP и EXIT и никто по этому поводу проблем не испытывал.
-
some_loop(...)
{
statement1;
if (condition) continue;
statement2;
}
эквивалентноsome_loop(...)
{
statement1;
if (!condition)
{
statement2;
}
}
Ну и зачем, спрашивается, нужен continue? Только для того, что бы уменьшить вложенность у statement2 (ценой ухудшения понятности кода)?
Очевидно, что он был введён для этого:
some_loop(...)
{
statement1;
if (!condition1)
{
statement2;
if (condition2)
continue;
}
}
А 1-й легкозаменимый вариант просто неизбежное следствие наличия ненужных конструкций в языке
-
Моё упущение, надо было так:
some_loop(...)
{
statement1;
if (!condition1)
{
statement2;
if (condition2)
continue;
}
statement3;
}
-
Вспоминается старый добрый FoxPro, у которого во всех циклах, включая аналог форыча SCAN были LOOP и EXIT и никто по этому поводу проблем не испытывал.
Ага. Проблемы испытывали/испытывают те, кто теперь в этих поделках пытается разобраться.
-
Ага. Проблемы испытывали/испытывают те, кто теперь в этих поделках пытается разобраться.
Гы. Фокспро вообще легендарная вещь в плане создания несопровождаемых программ. Циклы - лишь одно из средств...
-
Вспоминается старый добрый FoxPro, у которого во всех циклах, включая аналог форыча SCAN были LOOP и EXIT и никто по этому поводу проблем не испытывал.
Ага. Проблемы испытывали/испытывают те, кто теперь в этих поделках пытается разобраться.
А это проблема та же, что сейчас в 1С - код, написанный профессиональными программистами, легко понимается и сопровождается, а остальные поделки, написанные наспех обученными школьниками, анализу не поддаются )))
К тому же, языковые конструкции здесь не причём - если в голове бардак, то ничто не спасёт, об этом уже 100500 раз говорилось.
-
Думаю(вернее надеюсь), что если запретить форыч, бряки и контины, то многие говнокодеры внезапно станут профнепригодны.... Ну или им придется таки повышать свою квалификацию. :)
-
Они перестанут писать циклы вообще ))
В до-синт-сахарные времена так и было - говнокодеры дико боялись писать сколь-нибудь непримитивный цикл и бежали искать библиотеку/компонент.
Если для Delphi не находилось готового компонента - шли к начальству и докладывали, что задача неразрешима на данной фазе научно-технического прогресса.
-
Они перестанут писать циклы вообще ))
В до-синт-сахарные времена так и было - говнокодеры дико боялись писать сколь-нибудь непримитивный цикл и бежали искать библиотеку/компонент.
Если для Delphi не находилось готового компонента - шли к начальству и докладывали, что задача неразрешима на данной фазе научно-технического прогресса.
Сейчас также. И дело не в циклах.
-
Сейчас также - это ясно ))
Я про другое - что в своём коде старались не писать циклов вообще, кроме самых тупых for.
Даже всерьёз давались советы: "Если вы видите, что вам требуется цикл сложнее, чем for, поищите библиотечную функцию и не изобретайте велосипед".
-
Сейчас также - это ясно ))
Я про другое - что в своём коде старались не писать циклов вообще, кроме самых тупых for.
Даже всерьёз давались советы: "Если вы видите, что вам требуется цикл сложнее, чем for, поищите библиотечную функцию и не изобретайте велосипед".
У функциональных программистов этот совет актуален и сейчас: если вы видите, что у вас получилась рекурсия, попробуйте переделать функцию с использованием стандартных map/reduce/filter/zip. :P
-
Сейчас также - это ясно ))
Я про другое - что в своём коде старались не писать циклов вообще, кроме самых тупых for.
Даже всерьёз давались советы: "Если вы видите, что вам требуется цикл сложнее, чем for, поищите библиотечную функцию и не изобретайте велосипед".
У функциональных программистов этот совет актуален и сейчас: если вы видите, что у вас получилась рекурсия, попробуйте переделать функцию с использованием стандартных map/reduce/filter/zip. :P
Это вообще очень хороший совет - по возможности использовать более узкоспециализированные высокоуровневые вещи вместо чуть причесанного синтаксически goto. Просто потому, что в этом случае при чтении кода лучше будет понятна суть происходящего.
-
Знаешь, глядя на вызов какой-то специализированной функции (допустим, коих в каком-нибудь быдло-скрипте типа PHP сотни), я должен гадать, что она делает, хотя это могло быть записано 3-5 строками кода, про который ничего не нужно гадать :)
Не напастись стандартных решений на все нестандартные ситуации. При динамичном перемещении в пространстве Проще получить права (научиться грамотно программировать) и купить автомобиль (использовать инструменты-языки универсальной категории, а не высокозасахаренные), чем пытаться покрыть все свои потребности общественным транспортом или заказом такси :)