Здравствуйте, LaptevVV, Вы писали:
mgu>>А что плохого в goto? Когда-то написали в газете "Правда", что это плохо, и все повторяют, но никто не может объяснить. LVV>Опять же — читайте классиков! LVV>Писал Дейкстра, писал Кнут.
Что бы они ни писали, не нужно их считать безусловными авторитетами претендующими на абсолютное знание.
LVV>Основная мысль состоит в том, что такой код (напичканный goto) LVV>а) трудно читать LVV>б) трудно модифицировать.
Но for, while -- тоже замаскированные goto. А switch-case в C/C++ вообще страшная вещь в контексте того, что case можно вставлять в середину какого-либо другого цикла или даже ветви if'а. Если развивать мысль в этом направлении дальше, то циклы стоит запретить и всё делать через рекурсию. Разговоры вокруг и около goto сводятся к поговорке "заставь дурака богу молиться..."
Однако практически за 50 лет goto так и не пропал, как и longjmp, как и switch-case. В них есть смысл. Разумеется не для изоморфного переноса блок-схемы алгоритма в функцию языка программирования, как делают некоторые студенты.
LVV>Структурное программирование хорошо тем, что каждая конструкция имеет ОДИН вход и ОДИН выход. LVV>Это значительно упрощает как чтение, так и модификацию.
Не соглашусь в общем случае. Практически может быть удобно иметь выходы из функции в случае ошибок немедленно, чем устраивать 10-кратной вложенности if'ы только ради того, чтоб иметь единственный return в конце. Последний вариант как раз трудно читать и трудно модифицировать.
Да и вдалбливаемая студентам мысль, на счёт программы как _последовательности_ инструкций она как бы несколько порочна. Проблему как раз заложили первопроходцы структурного программирования в языках типа фортран, паскаль и т.п. Где вместо понятия вычисляемого выражения появилось понятие последовательности инструкций вместо вычисляемого выражения. В C/C++ теперь есть и то и другое, например в выражении "return x ? y : z" сколько выходов? Если ветви по которым может пойти вычисление две.
LVV>>Писал Дейкстра, писал Кнут. fk0> Что бы они ни писали, не нужно их считать безусловными авторитетами претендующими на абсолютное знание.
В данном случае конкретно статья Кнута была не мнением, а исследованием.
Вывод Кнута (на основании исследований кода программ на фортране) однозначен: использование goto без должной дисциплины приводит к большему количеству ошибок.
Это — НАУЧНЫЙ результат. LVV>>Основная мысль состоит в том, что такой код (напичканный goto) LVV>>а) трудно читать LVV>>б) трудно модифицировать. fk0> Но for, while -- тоже замаскированные goto. А switch-case в C/C++ вообще страшная вещь в контексте того, что case можно вставлять в середину какого-либо другого цикла или даже ветви if'а. Если развивать мысль в этом направлении дальше, то циклы стоит запретить и всё делать через рекурсию. Разговоры вокруг и около goto сводятся к поговорке "заставь дурака богу молиться..."
Ни for, ни while не являются замаскированными goto.
А переключатель вообще-то в парадигму структурного программирования не входит...
Рекурсия — наше все в функциональных языках. Имеет место быть отсутствие goto обычно в таких языках (хотя мож где и есть, но я сомневаюсь).
Насчет дураков.
По известной формуле:
10% программеров всегда делают "правильно", 10% программеров — всегда "дураки", 80% — то так, то эдак.
Этим -то как раз прописанные правила и нужны.
Это как в библии: 10% людей выполняют заповеди всегда (даже при отсутствии прописанных заповедей), 10% — не выполняют никогда, а 80% — как написан, для них заповеди и писали.
Или как в шахматах.
Всегда начинающим говорят: конь на краю доски — плохо.
Но гроссмейстеры частенько так играют. Потому как они — гроссмейстеры. Те самые первые 10%. fk0> Однако практически за 50 лет goto так и не пропал, как и longjmp, как и switch-case. В них есть смысл. Разумеется не для изоморфного переноса блок-схемы алгоритма в функцию языка программирования, как делают некоторые студенты.
Есть — для гроссмейстеров. Но не для начинающих неофитов. LVV>>Структурное программирование хорошо тем, что каждая конструкция имеет ОДИН вход и ОДИН выход. LVV>>Это значительно упрощает как чтение, так и модификацию. fk0> Не соглашусь в общем случае. Практически может быть удобно иметь выходы из функции в случае ошибок немедленно, чем устраивать 10-кратной вложенности if'ы только ради того, чтоб иметь единственный return в конце. Последний вариант как раз трудно читать и трудно модифицировать.
Для выхода из функции немедленно есть исключения.
Их и назвали по-другому, чтобы различать легитимные вычисления и нелегитимные. fk0> Да и вдалбливаемая студентам мысль, на счёт программы как _последовательности_ инструкций она как бы несколько порочна. Проблему как раз заложили первопроходцы структурного программирования в языках типа фортран, паскаль и т.п. Где вместо понятия вычисляемого выражения появилось понятие последовательности инструкций вместо вычисляемого выражения. В C/C++ теперь есть и то и другое, например в выражении "return x ? y : z" сколько выходов? Если ветви по которым может пойти вычисление две.
Выход — ОДИН! Возвращаются разные значения — это да.
Чтобы было 2 выхода, должно быть два return.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, Pzz, Вы писали:
Pzz>Компилятор и не следит, следит отдельная утилита. Компилятору, по большому счету, все равно, а вот любой IDE навязывает стиль, причем один и тот же. Это раздражает первые два дня, а потом понимаешь, что это правильно.
Да? Ну попробуй в другом редакторе написать и скомпилировать потом.
Pzz>Что до школоты, это вряд ли. Ключевые люди там, в основном, все взрослые и уже отметившиеся в более других общеизвестных проектах (некоторые из этих проектов, впрочем, нонешняя школота может и не упомнить).
Тем не менее это сраные уроды.
Здравствуйте, LaptevVV, Вы писали:
VV>>>Структурное программирование хорошо тем, что каждая конструкция имеет ОДИН вход и ОДИН выход. LVV>>>Это значительно упрощает как чтение, так и модификацию. fk0>> Не соглашусь в общем случае. Практически может быть удобно иметь выходы из функции в случае ошибок немедленно, чем устраивать 10-кратной вложенности if'ы только ради того, чтоб иметь единственный return в конце. Последний вариант как раз трудно читать и трудно модифицировать. LVV>Для выхода из функции немедленно есть исключения. LVV>Их и назвали по-другому, чтобы различать легитимные вычисления и нелегитимные.
Ох нет. Исключения не предназначены для того, чтобы участвовать в нормальном потоке управления, они -- для исключительных ситуаций, ошибок. Это не выход из функции, это longjmp. Большой и тяжелый. И ещё где-то на стороне -- сохранённый контекст, чтоб было куда возвращаться. И возврат в совершенно другое место (вот где "два выхода").
Я хотел показать, что выражение такого вида:
return a ? b : c ? d : e ? f : g
эквиэвалентны следующему:
if (a) return b;
if (c) return d;
if (e) return f;
return g;
Где как раз виднеются "множественные выходы из функции". И ничего плохого в них нет. Иначе следовало бы признать первое выражение порочным.
А попытка такой код записать "с одним выходом" часто кончается многоуровневыми вложенными if-блоками, в которых точно легко запутаться. Это наверное должнно быть очевидно. Такой код точно "трудно читаемый" и всё прочее. Не дай бог там где-то ещё и else -- ошибки практически гарантированы.
fk0>> Да и вдалбливаемая студентам мысль, на счёт программы как _последовательности_ инструкций она как бы несколько порочна. Проблему как раз заложили первопроходцы структурного программирования в языках типа фортран, паскаль и т.п. Где вместо понятия вычисляемого выражения появилось понятие последовательности инструкций вместо вычисляемого выражения. В C/C++ теперь есть и то и другое, например в выражении "return x ? y : z" сколько выходов? Если ветви по которым может пойти вычисление две. LVV>Выход — ОДИН! Возвращаются разные значения — это да. LVV>Чтобы было 2 выхода, должно быть два return.
Проблема в наличии словосочетания "выход" из функции. Выхода как такового не существует. Выход -- это то чему присваивается регистр PC после собственно выхода и он уж точно всегда один (а в случае "выхода по исключению" оно запросто может оказаться совсем другой точкой в программе). Если не воспринимать программу как последовательность инструкций (то, что нужно выжечь калёным железом и запретить такое словосочетание, для студентов в первую очередь), а как набор логических правил позволяющих выполнить вычисления, то вопрос о количестве выходов из функции даже встать не может. Нет у функции такой сущности как выход. Функция -- это способ отобразить множество значений аргументов на другое множество выходных значений. Не нужно думать, что процессор будет программу последовательно по строчкам выполнять. С современными компиляторами порядок давно может оказаться очень странным. Важно лишь какое правило применяется. И не важно сверху-вниз, снизу-вверх или ещё как записана программа.
И смысла считать количество операторов return в функции, кроме слепого следования безумной идее, мол "выход должен быть один" нет. Равно как тщательности в избегании goto и прочих "вредных практик". Вредные они только в отдельных очумелых ручках, но не следует из этого распространять некие мифические правила правильного программирования на всю отрасль. Серебряной пули нет. В практических языках программирования не просто просто так есть return (можно было бы сделать как в octave/matlab, через присвоение переменной, и убрать return), не зря есть goto или break с параметром или last с меткой. 40-50 лет уже есть и конца не видно. И только в "учебных" ЯВУ встречаются какие-то дикости, вроде запрета goto. Если инструмент позволяет выстрелить себе в ногу, то не обязательно этой возможностью следует воспользоваться. А если эту возможность отобрать, то получится детская игрушка не пригодная для практических задач, где таки стрелять нужно уметь, и иногда даже в ногу.
Эти практики вызывали ошибки в фортране? Это не goto плох, а его использование. В gcc два десятилетия есть computed goto и switch в обычном C/C++ ещё больше есть. Не слышно о серьёзно пострадавших. Не нужно подменять понятия. goto достаточно хорош для обычного программирования и только в особо неопытных руках может применяться каким-то диким образом. Но это не значит что goto плохой, или его не следует использовать. Его лишь нужно УМЕТЬ использовать.
Можно сделать return и забыть что-то, например мьютекс, на выходе из функции? Не нужны костыли в виде единственного return (о чем легко забыть и никто не проверит), а нужно либо завернуть основную часть функции в отдельную функцию (лямбду, локальный класс), или использовать в C++ локальные инстансы объектов с соответствующим деструктором. Вот хорошая практика, а единственный return -- костыль, причём плохой.
Здравствуйте, LaptevVV, Вы писали:
mgu>>А что плохого в goto? Когда-то написали в газете "Правда", что это плохо, и все повторяют, но никто не может объяснить. LVV>Опять же — читайте классиков! LVV>Писал Дейкстра, писал Кнут. LVV>Но статьи старые, в русском инете не найти. Может быть, есть в английском.
Ну, классики много чего говорили. И про богоугодность каскадной разработки, и про 640 килобайт памяти, и про важность гномиков на интервью.
LVV>Основная мысль состоит в том, что такой код (напичканный goto) LVV>а) трудно читать LVV>б) трудно модифицировать. LVV>Структурное программирование хорошо тем, что каждая конструкция имеет ОДИН вход и ОДИН выход.
Меня терзают смутные сомнения, что return -- это замаскированный goto.
LVV>Это значительно упрощает как чтение, так и модификацию.
С таким подходом бывает, что код заносит вправо за область видимости монитора.
Кстати, "ОДИН выход" уже несколько лет как подвергли анафеме. Ещё недавно в обязательный номер цирковой программы на интервью входило прочитать "catch наш" в правильном порядке. А нынче во все стороны кидаются исключениями, событиями и задержками.
А в старом добром HTML-е один вход, а выхода нет. При этом к структурированности не придерёшься.
А ещё есть yield -- это вообще проходной двор.
Здравствуйте, RussianFellow, Вы писали:
RF>Когда я учился в институте, у нас не было никакого code review. И на нынешней и на всех предыдущих работах у меня не было никакого code review. RF>Главное--чтобы код работал и работал правильно.
Судя по всему, что ты тут пишешь — у вас за ревью прораб отвечает, он же сапогами и пинает непрошедших его прораб-ревью
Здравствуйте, kaa.python, Вы писали:
V_S>>Валерий Викторыч, это отнюдь не кодревью и не "хороший стиль", а — "стиль, который нравится профессору". Ваш-то код кто-нибудь ревьюит?
KP>Какой-то стиль всяко нужно взять за образец и считать именно его правильным. Чем стиль профессора плохой образец для студентов?
Может тем, что он сам никогда не проходил никаких код-ревью?
Здравствуйте, Vlad_SP, Вы писали:
KP>>Какой-то стиль всяко нужно взять за образец и считать именно его правильным. Чем стиль профессора плохой образец для студентов?
V_S>Стиль профессора может быть и не плохой образец для студентов. Однако если цель кодревью — только "исправление стиля", типа исправления расстановки скобочек (Kernighan vs Allman etc.), то это пустая трата времени.
За оформление кода в стиле KnR пожизненный эцих с гвоздями
Здравствуйте, Pzz, Вы писали:
V_S>>Стиль профессора может быть и не плохой образец для студентов. Однако если цель кодревью — только "исправление стиля", типа исправления расстановки скобочек (Kernighan vs Allman etc.), то это пустая трата времени.
Pzz>Вот чем хорош язык Go, в нем есть один единственный правильный стиль, который жестко енфорсится редактором текстов. И это сразу снимает все вопросы по стилю. И очень освобождает руки от форматирования текста.
Это что, в Го как Пайтоне? Или это просто какой-то "правильный" редактор следит, но в общем случае пох?
Здравствуйте, LaptevVV, Вы писали:
LVV>>>Как тогда учить студентов хорошему стилю и рефакторингу? V_S>>Валерий Викторыч, это отнюдь не кодревью и не "хороший стиль", а — "стиль, который нравится профессору". Ваш-то код кто-нибудь ревьюит? LVV>"Мастерство не пропьешь"(с)... LVV>Около 50 лет опыта, прочитано литературы едва ли не больше всех в России.
Здравствуйте, LaptevVV, Вы писали:
LVV>>>Как тогда учить студентов хорошему стилю RF>>У каждого программиста--свой стиль. Главное, чтобы код был читаемый. LVV>Нет. Есть общие признаки хорошего стиля. LVV>Читайте классиков: МакКоннелл, Саттер+Александреску.
Вот Александреску как пример для подражания так себе
Здравствуйте, LaptevVV, Вы писали:
mgu>>А что плохого в goto? Когда-то написали в газете "Правда", что это плохо, и все повторяют, но никто не может объяснить. LVV>Опять же — читайте классиков!
Для плюсов готу ломает автоматику управления локальными объектами, не?
LVV>>Нет. Есть общие признаки хорошего стиля. LVV>>Читайте классиков: МакКоннелл, Саттер+Александреску. M>Вот Александреску как пример для подражания так себе
Я — про общую их книжку по стилю программирования на С++.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
LVV>>"Мастерство не пропьешь"(с)... LVV>>Около 50 лет опыта, прочитано литературы едва ли не больше всех в России. M>Это серьёзная заявка
А то...
Но, конечно, чтобы читать какой-то курс — надо к нему готовиться полгода.
В свое время, лет 20 назад, наш тогдашний завкаф сказала: Лаптева клонировать надо.
Что ни спросишь — он знает, в каких книжках и что прочитать...
А вообще-то после разработки и написания бортовой оси — что может быть непонятного в программировании?
Вопрос только во времени — готовиться надо.
Самое сложное — лабы продумать и написать.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
mgu>>>А что плохого в goto? Когда-то написали в газете "Правда", что это плохо, и все повторяют, но никто не может объяснить. LVV>>Опять же — читайте классиков! LVV>>Писал Дейкстра, писал Кнут. LVV>>Но статьи старые, в русском инете не найти. Может быть, есть в английском. mgu>Ну, классики много чего говорили. И про богоугодность каскадной разработки, и про 640 килобайт памяти, и про важность гномиков на интервью.
Ну, это не классики...
... mgu>Кстати, "ОДИН выход" уже несколько лет как подвергли анафеме. Ещё недавно в обязательный номер цирковой программы на интервью входило прочитать "catch наш" в правильном порядке. А нынче во все стороны кидаются исключениями, событиями и задержками.
Ну, пишите, как хотите. Структурное программирование — это только рекомендации... mgu>А в старом добром HTML-е один вход, а выхода нет. При этом к структурированности не придерёшься.
А это вообще не язык программирования mgu>А ещё есть yield -- это вообще проходной двор.
Это в питоне, что ли?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
LVV>>>Нет. Есть общие признаки хорошего стиля. LVV>>>Читайте классиков: МакКоннелл, Саттер+Александреску. M>>Вот Александреску как пример для подражания так себе LVV>Я — про общую их книжку по стилю программирования на С++.
Это про "Стандарты прогрпммарования на C++" Герб Саттер, Андрей Александреску?
Если так, то это великолепная книга. Авторы всё очень толково изложили.
Здравствуйте, mgu, Вы писали:
mgu>Меня терзают смутные сомнения, что return -- это замаскированный goto.
Нет, это НЕ замаскированный goto!
Ключевое отличие return — переход НЕ ПО МЕТКЕ, а по сохраненному в стеке адресу возврата.
Это позволяет передавать управление не на фиксированную точку, а именно туда, откуда был вызов.
Мы выделили четыре пункта, которые должны быть в обновленном код-ревью:
1. Проверка архитектуры решения. Довольно очевидная вещь. Ожидаем это от старших разработчиков с экспертизой в данном компоненте.
2. Проверка технической реализации, которую ожидаем также от старших и мидлов с экспертизой в данном компоненте.
3. Передача знаний, которая заключается в изучении бизнес-логики и кодовой базы новичками и джунами посредством код-ревью.
4. Возможность оценки hard skills разработчиков. Хочется, чтобы за каждым разработчиком был закреплен наставник, который оценивает рост, определяет вектор развития, подмечает какие-то недостатки, делает замечания и так далее. Поэтому наставник также должен видеть код своих подопечных.
Возможно, кто-то видит другие цели или не согласен с нашими — делитесь в комментариях. А я пока перейду от формулирования целей к поиску средств их достижения – мы решили, что хотим достичь их все и (почти) сразу.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, Marty, Вы писали:
mgu>>>А что плохого в goto? Когда-то написали в газете "Правда", что это плохо, и все повторяют, но никто не может объяснить. LVV>>Опять же — читайте классиков!
M>Для плюсов готу ломает автоматику управления локальными объектами, не?
Компиляторы сейчас за этим следят, но для POD типов можно такого наколбасить...
_____________________
С уважением,
Stanislav V. Zudin