Как стать автором
Обновить

Комментарии 243

полностью поддерживаю!

self-explanatory code должен превалировать над «пока-мыл-посуду» коментариями.
отсутсвие коментариев оправдано если код написан людьми для людей.

Я всегда считал, что в хорошем коде комментарии бывают только двух типов:

0) объясняющие зачем
#define TRUE FALSE; // умрите с*ки!


1) бессмысленные
int error_code; // код ошибки


Комментарии могут объяснить «зачем», но никогда «как». «Как» — должен обяснять сам код, если он не объясняет, то никакие комментарии не помогут.
Я прям читаю, и вижу цитату из книги Фаулера. Полностью поддерживаю!
Иногда встречается случай, когда некоторые джуниор программисты стараются сохранить таким образом код, который потом, «когда-нибудь» может понадобиться. Вот с этим довольно сложно бороться.
Не всегда это так.
Комментарий может ещё объяснить, что здесь вообще делается и почему именно так.
Комментарий может объяснять, как в данном конкретном месте решена задача, если сам код плохо читается.
То есть это кейсы в которых комментарий позволяет быстрее разобраться в коде, не вникая глубоко в каждую строчку.

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

Например, на C++ обычный код заменён ассемблерным фрагментом — нужен комментарий о том что тут делается и как.

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

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

В этом случае, вначале нужен комментарий зачем, потом про суть алгоритма, но не описание самого алгоритма.

> Например, на C++ обычный код заменён ассемблерным фрагментом — нужен комментарий о том что тут делается и как.

Если семантика языка не позволяет писать понятный код, то комментарии должны это восполнить:
mov AX, BX; AX = количество попугаев в клетке

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

В этом случае нужен комментарий с описание проблемы, и сутью решения (это и есть ответ на вопрос «зачем»). Описание алгоритма не нужно.
К сожалению в академической среде, руководствуясь этим по-видимому этим правилом, не то что комментарии не пишут, а документацию не делают. Поэтому по-моему все же лучше комментариев больше чем нужно, чем ну у нас же код и ежу понятен!
Конечно не все академисты так делают, но с примерами этого сталкиваюсь и сталкивался
Ну вот я например сейчас пишу академический код. Работаю над исследовательским проектом, который непонятно куда заведет в итоге, перелопачиваю кучу статей, пишу, соединяю, тестирую и выбрасываю разные алгоритмы, чтобы найти ту их комбинацию, которая решит мою задачу. В таком режиме гораздо сложнее поддерживать высокие стандарты кодирования, потому что никогда не знаешь, во что превратится и останется ли вообще в живых через несколько дней очередной класс. При этом, я совершенно отдаю себе отчет, что этот конкретный код мало кому интересен. Если я получу заслуживающие внимания результаты, они будут опубликованы, и на основании описания те, кому это надо, будут делать промышленный код. Поэтому я совершенно сознательно не уделяю должного внимания тестам и нарушаю время от времени святой DRY. Если же делать по-нормальному, время работы вырастет в несколько раз, а результат будет тот же.

Другое дело, если академики пишут код для уже обкатанных решений, который предназначается для широкого использования. Тогда да, надо делать по уму. Но многие вместо полного переписывания прототипов пытаются сэкономить, реюзая экспериментальные поделки.
А вы когда-нибудь писали не академический код?
Было дело.
Ну когда прототипирование идет, да еще и в исследовательских целях ясно что пренебречь комментарием нестрашно, если точно понимаешь что делаешь. Когда наталкиваешься же на Open Source код программ от лабораторий и т.д., где комментариев нет или практически нет, а вместо документации-форум \рассылка уже неприятно, а когда сталкиваешься с внутренними продуктами универа, которые пилят под свои задачи и там опять же нет вменяемой документации, а держится все на личном общении с разработчиком, то становится весьма неудобно работать. Поэтому комментарии по мне все же полезная штука и лучше, если не сразу комментить, то после написания модуля/финального прогона, взять и задокументировать
Даже при протипировании типа «попробуем такой-то вариант из журнала, SO, хабра, ...» полезно давать ссылку на источник хотя бы для самого себя, чтобы на следующий день вспомнить откуда взялся рабочий вариант из десятка нерабочих.
Раньше, наверное, я мог бы давать ссылку на «страничку 143 из тетради-черновика №9». Но теперь черновики пишутся и очень быстро стираются в электронном блокноте, так что программа остаётся единственным представлением алгоритма. При этом она написана совсем не в тех терминах, в которых формулировался алгоритм: например, в черновике шла работа с дробно-линейными функциями над комплексными числами, а в программе по сложным формулам строится матрица 6*7… алгоритм при этом тот же самый.
Куда давать ссылку? Отправлять себе по почте странички из черновика перед их уничтожением?
Но теперь черновики пишутся и очень быстро стираются в электронном блокноте,

Включение .txt файла в репозиторий в качстве документации, с постоянными коммитами его изменений?
Файлы там не txt, а какие-то snb (и совершенно непонятно, как их читать в Windows). Правда, можно их конвертировать в jpg или pdf, и в таком виде переносить в репозиторий. Проблема в том, что алгоритм в блокноте разрабатывается только до того момента, когда я, глядя на эти каракули, смогу сконвертировать их в код. Шансов на то, что кто-нибудь, кроме меня, сможет разобраться во взаимосвязи между этими представлениями, мягко говоря, немного.
Ну и, как говорили выше, «никогда не знаешь, во что превратится и останется ли вообще в живых через несколько дней очередной класс». Так что, если отправлять все черновики, когда-либо превращавшиеся в код, то там скопится столько же мусора, сколько его бывает в коде, в котором старые версии функций и классов не удаляются, а комментируются. Синхронизации-то нет…
Но надо это обдумать. Потому что если я начну описывать уже реализованные алгоритмы, то только на эту работу уйдёт полгода, а где их взять?
гугл говорит, что .snb — это просто .zip с jpeg'ами внутри.
Может быть, но не очень просто. Это действительно zip, где-то в его недрах есть thumbnailimage.jpg (не интересный), и какой-то png. На первый взгляд, в нём пусто, дальше не смотрел — уже видно, что технически проще экспортировать jpg прямо из SNote.
В такой ситуации комментарии (как и прочие best-practices) безусловно нужны.
Мне постоянно приходится так работать. В коммерческом проекте…
Ну сам показатель того, что проект коммерческий, мало что значит. Но если у вас стабильная база кода, много юзеров, которые его используют и так далее, то конечно нужно все экспериментальные части выносить в отдельные проекты или ветки репозитория, а в основные ветки коммитить уже по уму — с тестами, комментариями и паттерном Абстрактная фабрика, там где он уместен.
А интересно, например, у Вас в проекте применяются системы генерации документов типа Doxygen, так как, конечно, такая документация не идеальна, но по хорошо составленным комментариям позволяет создать хотя бы справочник, чтобы не заблудиться. У меня, например, про системы генерации документации судя по всему не слышали, но к их применению отнеслись положительно.
У меня сейчас маленький проект, я его один ковыряю, поэтому сильно не заморачиваюсь. Комментарии стараюсь поддерживать в порядке, готовыми к генерации, но саму генерацию не использую. В компании, где работаю, применяется такой же подход для коммерческих приложений. Поскольку в моем отделе разрабатываются внутренние сервисы без предоставления внешнего API, комментарии из кода обычно никто не выдергивает.
Бывает. Но и ситуации бывают разные, я бы выделил два крайних случая.

0) Вы работаете в одиночку на своим стартапом, и Вы считаете себя неплохим программистом. Если это так, то Вы можете сосредоточиться на написании «идеального кода» немного в ущерб скорости разработки. Вы будете правильно писать комментарии, делать хорошие юнит-тесты, и т.д., а время, потраченное на мысли по улучшению кода, расценивать как самообучение и профессиональный рост.

1) Вы руководите наемной группой разношерстных программистов. Вам нужен результат. Вам крупно повезет, если в этой группе будет хотя бы один программист, который может писать хороший код (хотя скорее всего его не будет: у него есть своя группа и свой проект). Вопрос что делать? Учить их? Это лишнее время и результат непредсказуем (ситуацию может усложнить отсутствие у Вас способностей учить). Что делать? Во-первых, смириться с тем, что их код будет далек от идеального. Во-вторых, написать стандарты+инструкцию по написанию кода в этом конкретном коллективе. Эта инструкция должна не противоречить написанию идеального кода, но быть существенно проще. Значит требования инструкции будут сильно формализованы и, следовательно, будет требование избыточного комментирования, избыточного тестирования, и т.д.

Красота vs. Конвеер.

Искусство vs Технологический процесс.
НЛО прилетело и опубликовало эту надпись здесь
А что это за листинг на 300+ строк? Одна функция/модуль? Класс? Программа?
Можете почитать, например, исходники nginx'а. Там встречаются файлы, в которых несколько функций занимают сотни строк кода, а комментариев нет. Воспринимается с трудом.
Мы комментируем только нетривиальные участки кода, без которых не обойтись. В остальных случаях отдается приоритет простому и читабельному коду.
Так или иначе. Когда функция не умещается на экране, ее с натяжкой можно назвать простой и читабельной.
Это очень странный критерий. Примерно как утверждать, что роман Война и Мир не читабелен, поскольку не уместился даже в один том. Можно написать две строчки кода, на которые каждый будет смотреть и 5 минут тупить, а что же они всё-таки делают, и зачем, а можно написать стейтмашину из 50 состояний и всем ясно, как она работает, хотя занимает не один, и не два, а 10 экранов. Сложность кода определяется не его объемом, а логической простотой.

Пример нетривиального кода, который потребовал комментария:
3397	    /*
3398	     * Setting r->pool to NULL will increase probability to catch double close
3399	     * of request since the request object is allocated from its own pool.
3400	     */
3401	
3402	    pool = r->pool;
3403	    r->pool = NULL;
3404	
3405	    ngx_destroy_pool(pool);

Как видно и сам код выглядит простым, и это кусок функции в которой всего то строк 20 кода. Но у читателя может возникнуть недоумение: зачем в объекте запроса за'null'ять ссылку на пул, если следующей же строчкой мы освобождаем всю память, где был и объект запроса, и сам пул.
С вашим доводом в пользу комментария к непонятному короткому куску кода я не спорю, а вот критерий не такой уж и странный. Он довольно известный, и его легко обосновать. Когда человек не видит всю функцию целиком, ему приходится помнить скрытый в данный момент кусок кода, чтобы сложилась полная картина происходящего. Чем труднее его запомнить, тем больше времени тратится на чтение и понимание. И без того приходится помнить структуру программы в целом, а вы еще усложняете задачу.

Надо отметить, что названия переменных в духе clcf, e, of, tf и многочисленные goto в вашем коде также не способствуют легкому восприятию. Еще накладывается, что переменные, несущие один и тот же смысл, иногда называются по-разному. Например:

ngx_http_core_loc_conf_t *clcf;
// vs
ngx_http_core_loc_conf_t *pclcf;

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

В принципе, почти весь код на С, который я видел, мало отличается от вашего, разве что длиной функций. Думаю, это считается нормальным среди С программистов так писать, но читабельным от этого код не становится.

Кстати, если взять процент людей, которые начали читать Войну и Мир и дочитали до конца, то можно сказать, что книга действительно нечитабельна :)
Когда человек не видит всю функцию целиком, ему приходится помнить скрытый в данный момент кусок кода, чтобы сложилась полная картина происходящего.
А если разбить эту функцию на 10 функций, очевидно завязанных друг на друга, то автоматически сразу нужно будет меньше помнить? Или код станет проще? По факту он может стать даже сложнее, ибо тесно связанный кусок кода просто ввиду алгоритма могут плохо разбиваться на отдельные функции, или у этих функций будет 10 параметров. Уж не говоря о том, что это однозначно усложнит трассировку кода. Вместо того, чтобы читать код сверху вниз, придется читать его мелкими отрывками (отдельными функциями) и вникать в суть их взаимодействия.

Не бывает такое в программирование, что большая функция — однозначно плохо, а 10 маленьких — однозначно хорошо и что-то улучшит. Излишнее стремление плодить мелкие функции — такой же вред, как отказаться от функций совсем. Функции нужны не для уменьшения строк кода (как некоторые видимо думают), а для разбиения кода на логические, независимые блоки, а также дедупликации этих блоков. Если же блоки кода зависимы друг от друга и связаны так, что развязать их без усложнения логики не представляется возможным, то нахождение их рядом — логично и упрощает понимание.

названия переменных в духе clcf, e, of, tf
clcf (718), e (556), of (684), tf (115) — в скобках указано количество раз, которое эти сокращения используются. Cокращения для часто используемых переменных, и не только, необходимы, поскольку это существенно уменьшает визуальный шум. Замените в 718-ти местах clcf на core_local_configuration, e на script_engine — и посмотрите как это будет выглядить. Ужасно будет. Код nginx-кса и так страдает от слишком длинных префиксов просто в угоду глубокой иерархической структуры модулей.

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

ngx_http_core_loc_conf_t *clcf;
// vs
ngx_http_core_loc_conf_t *pclcf;


Промотав на конец 100-строчного метода, в начале которого объявлены переменные, мне уже требуется усилие, чтобы помнить тип каждой из них.
Все-таки там где они встречаются — это разные переменные, с разным смыслом. Знание типа нисколько не поможет без знания смысла, а если смысл ясен, то и тип самоочевиден, помнить его нет необходимости.

Кстати говоря, nginx несмотря на 100к строк кода — один из немногих проектов, код которого можно легко редактировать и писать без какой-либо IDE, в простом текстовом редакторе, типа nano, и это не доставляет каких-либо неудобств, что я в общем-то и делаю уже который год. Не это ли лучший показатель его простоты?

В принципе, почти весь код на С, который я видел, мало отличается от вашего, разве что длиной функций. Думаю, это считается нормальным среди С программистов так писать, но читабельным от этого код не становится.
Ну извините, если вы плохо знакомы с языком программирования на котором написан код, то разумеется он будет казаться плохо читабельным. А взять простого обывателя, так для него любой код будет малопонятной простыней из буковок и значков.
Моё имхо конечно, но всё же, прошу задумайтесь:

1) Рефакторить долго живущий код, и приводить его к удобочитаемому виду — надо.
2) Длинные функции — зло, если их можно логически хорошо разделить по функционалу — это надо сделать. Об этом вы написали, и очень верно указали, что не все алгоритмы хорошо делятся, но в большинстве случаев это можно сделать.
3) Сокращать имена переменных, или функций, или чего бы то ни было ещё — вредно, ибо это мешает читать код, исключение — общепринятые сокращения (html, tcp, www), configuration тоже можно легко сократить до cfg, ибо при этом всё ещё сохранится смысл. Если уж так хотелось сократить script_engine, сократили бы хотя бы до se, и то данное сокращение не совсем очевидно.
4) Разрабатывать в блокноте — нельзя, ибо долго, и не удобно. А самое главное заставляет нарушать пункт 3. Тут я настоятельно прошу обратить внимание, что код в основном приходится читать, а не писать, и потому нарушение пункта 3 в угоду сомнительным возможностям недопустимо. Так же прошу обратить внимание, что провести адекватный рефакторинг в блокноте — невозможно.
5) Длинные префиксы — не проблема, их можно сокращать используя макросы, получается не так изящно как с namespace на С++, но проблемы на самом деле нет. Опять же, прошу обратить внимание, что если использовать IDE то проблем с написанием кода вообще не возникает из-за возможности авто подстановок.

Для примера: вот один из моих недавних мелких рефакторингов довольно простого кода, где, не смотря на исходную краткость, функциональное разделение принесло пользу: шаг 1, шаг 2, шаг 3.

Итог рефакторинга: убил большой кусок копипасты, провёл ревизию кода, выделил функционал, исправил найденные недоработки, и упростил внесение изменений в будущем за счёт унификации.

p.s: BaseChatFrame тоже был добавлен мной, при этом количество багов, которое было исправлено в ходе начального рефакторинга в этой области было просто невообразимое. Тогда, по сути простое структурирование кода, закрыло пару десятков тикетов в трекере в тех областях, и рядом с ними.
А если разбить эту функцию на 10 функций, очевидно завязанных друг на друга, то автоматически сразу нужно будет меньше помнить? Или код станет проще? По факту он может стать даже сложнее, ибо тесно связанный кусок кода просто ввиду алгоритма могут плохо разбиваться на отдельные функции, или у этих функций будет 10 параметров. Уж не говоря о том, что это однозначно усложнит трассировку кода. Вместо того, чтобы читать код сверху вниз, придется читать его мелкими отрывками (отдельными функциями) и вникать в суть их взаимодействия.

Во всем нужно знать меру. Километровые функции можно и нужно распиливать, но это не значит, что каждый шаг требует вынесения в отдельную функцию. Важно то, что каждая функция имеет имя, которое описывает выполняемое действие. При удачном подборе имен маленьких функций код большой функции превращается в набор простых предложений, который приятно читать. Никто не говорил, что процесс рефакторинга бывает легким, поэтому это ваша задача — избежать того, чтобы не было по 10 параметров там и тут. В конце концов, тема о комментариях, и если вам не нравится деление на функции, то можно было хотя бы сделать больше комментариев.

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

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

Это тесно связанные факторы. Хорошо разделенные, независимые и переиспользуемые блоки в конечном счете ведут к упрощению кода и препятствуют лавинообразному росту количества строк из-за копипасты.
Никто не предлагает дробить код на более мелкие части ради сокращения его размеров (действительно, кто эти «некоторые»?). Мотивация должна заключаться в хорошей самодокументированности результата.

clcf (718), e (556), of (684), tf (115) — в скобках указано количество раз, которое эти сокращения используются. Cокращения для часто используемых переменных, и не только, необходимы, поскольку это существенно уменьшает визуальный шум. Замените в 718-ти местах clcf на core_local_configuration, e на script_engine — и посмотрите как это будет выглядить. Ужасно будет.

Не впадайте в крайности. e достаточно заменить на engine, или вообще eng, и это уже будет лучше, потому что взгляд будет лучше различать, что это переменная, а не какая-нибудь цифра, к примеру. Однобуквенные переменные — вот что действительно ужасно. В следующий раз вы назовете переменную o, чтобы читатели офигевали, видя там и тут «нули».

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

Давайте не будем делать странные выводы о владении языком. Я достаточно хорошо знаю язык, и, если на то пошло, вы меня пока не убедили, что знаете его лучше меня. Но знание языка тут не при чем. Язык — это способ описать алгоритм. Способность записать его в как можно более понятной человеку форме — хороший навык, в то время как лапша в коде говорит о каше в голове. Неужели у вас не было такого, что одна книга читается легко и приятно, а другая идет тяжелее? В обеих слова-то одни и те же, и по вашей логике, если человеку трудно читать вторую книгу, значит он плохо знаком с русским языком.
Так может, это отрефакторить надо?
Ну, ситуация, когда у вас есть листинг одного метода на 300+ строк — это уже не очень хорошая ситуация. Повторюсь: скорее всего следует разбить этот большой метод на несколько маленьких. Тогда код основного метода будет у вас содержать строк 10-20 различных вызовов других маленьких методов. Т.е. основная логика метода будет нормально читаться и без комментариев. А основная задача метода (в идеальном проекте один метод выполняет одну конкретную задачу) должна быть понятна из его названия.
Но это всё общие рассуждения на тему абстрактного проекта. Они хороши в большинстве случаев, но не в 100%. Т.е. возможна ситуация в которой метод на 300+ приходится использовать, необходимость обоснована. Если в этом методе разобраться сложно, то почему бы не вставить комментарий на 4 строчки с важной и полезной информацией — ничего плохого в этом нет.
есть на памяти пара алгоритмов, которые особо нет смысла бить, а строк получается прилично.
Тут, мне кажется, не только в числе строк дело. Даже если строк всего 20и они легко читаются, то коментарий в начале поясняющий зачем эта штука вообще была создана — это сильно сэкономит время на решение вникать ли в эти пусть всего и 20 понятных строчек. Насчет названия оно верно, конечно, но физически не всегда воможно. Все же название длиной в полторы строки тоже не сильно удобно. Хотя пользователям Твиттера тут может и проще :)
Тот же дядюшка Боб пишет в своих книгах как избавляться от таких вещей, почему они плохи и как сделать лучше.
Всем, кому понравилась эта статья, очень интересно будет прочитать книгу Р. Мартин, «Чистый код. Создание, анализ и рефакторинг».
Если не считать *doc комментариев и аннотаций, то обычно в них пишу причину выбора данного вариант/алгоритма («округляем в меньшую сторону, чтобы случайно не остаться должными», «используем FIFO чтобы минимизировать максимальное время обработки — имхо, оно критичнее чем минимальное», «подобрано эмпирическим путем» и т. п.), либо ссылку на документацию («см. ТЗ в ред. от 11.06.2013 п.13.7 „) или иные внешние источники (“см. ru.wikipedia.org/wiki/Закон_Гука»). Ну и варианты типа «знаю, что костыль, то так заказчик захотел» встречаются.
Да, это нормальные комментарии. Они обращают внимание других разработчиков на важные вещи, объясняют непонятные моменты. Если они достаточно лаконичны (а не расползаются на мануал в 50 строчек), то их использование — хорошая практика.
Коллеги, пишите комментарии для Regexp, даже для простых, в стиле «проверяем, чтобы было три любых буквы и цифра в конце». У меня чаще всего эти комментарии пригождаются самому себе, когда функцию видишь снова через полгода.
Может тогда стоит использовать grammar-like regexps?
(?(DEFINE)
    (?<whole> (?&line)+ )

    (?<line> ( (?&no_mail_line) | (?&seen_mail_line) | (?&no_seen_line) ) \n )


    (?<seen_mail_line> (?&total_messages) \s messages? \s \((?&seen_messages) \s seen\) \s for \s (?&account_data) \. )
    (?<no_seen_line> (?&total_messages) \s messages? \s for \s (?&account_data) \. )
    (?<no_mail_line> fetchmail: \s No \s mail \s for \s (?&account_data) )

    (?<account_data> (?&account) \s at \s (?&server) \s \(folder \s (?&folder)\) )

    (?<account> [^ ]+ )
    (?<server> [^ ]+ )
    (?<folder> [^)]+ )

    (?<total_messages> \d+ )
    (?<seen_messages> \d+ )
)
^(?&whole)$
Фотки участников дискуссии подобраны очень годно.
А я у Мартина взял на заметку простое правило, что комментарии должны содержать намерения кода. Ведь не редко, читая чужой код бывает непонятно, что код должен делать по начальной задумке автора.
Да, это хорошее правило. Но сам Мартин также много пишет про то, что лучше бы, чтобы по коду задумка автора была понятна. Но если написать такой код не получилось, то комментарий с обозначением намерений лишним не будет.
Обратите внимание — для положительных случаев примеров нет
Для положительных случаев примеры являются менее показательными. Думаю, вы и так представляете как выглядит комментарий TODO, XML-доки или шапка с юридической информацией. Зачем перегружать статью лишними примерами? Отрицательные примеры являются более дискуссионными, хочется их как-то проиллюстрировать, чтобы была понятна основная идея — в этих случаях краткий сниппет заменяет несколько абзацев абстрактных рассуждений.
Да и иллюстрация к статье провакационная.
Я вот не соглашусь с тем, что не стоит комментировать код в котором можно разобраться и так. Можно, но с комментариями проще. Хороший пример — backbonejs.org/backbone.js. Библиотека обильно прокомментирована и разобраться в ее внутренностях достаточно просто, попробуйте удалить все комменты и почитать код, станет гораздо грустнее.
Ну разумеется без комментариев будет печально:

    // Remove one or many callbacks. If `context` is null, removes all
    // callbacks with that function. If `callback` is null, removes all
    // callbacks for the event. If `name` is null, removes all bound
    // callbacks for all events.
    off: function(name, callback, context) {

    // Start the hash change handling, returning `true` if the current URL matches
    // an existing route, and `false` otherwise.
    start: function(options) {

    // Checks the current URL to see if it has changed, and if it has,
    // calls `loadUrl`, normalizing across the hidden iframe.
    checkUrl: function(e) {

При такой экономии на вменяемых названиях, при впихивании в одну функцию десяти операций, при общей нетипизированности JS — разумеется, без комментариев можно удавиться. Но если так написан backbone.js, это не значит, что такой же код должен быть в проекте.
Я бы не назвал хорошим пример библиотеки, игнорирующей JSDoc и вместо этого запихивающей всю документацию в группы однострочных комментариев.

Перечитываю прямо сейчас дядю Боба, как раз главу про комменты.
Решил немного отвлечься и зайти на хабру…
товарищи преподаватели заставляли комментировать каждую строчку, «чтобы студент лучше разобрался»
Прошел я через такого преподователя, который заставлял коментировать каждую строчку, доходило даже до обсурда.
Приходилось к строчке int i = 0; писать коментарий

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

Человек писавший лапшу на бейсике (еще на том, классическом, с номерами строк) прекрасно понимает, что без кучи комментариев это лапшу не разобрать. Потом были включения ассемблерного кода в сях или паскале. Тоже надо было много комментировать.
Тогда не было всяких гитхабов… черт, тогда даже ООП было не особенно распространенным, и многие базовые языки его не поддерживали.
Попробуйте написать пару мегабайт кода, выделяя каждый небольшой блок в вспомогательную функцию или процедуру. Без классов.
Хочу посмотреть как вы будете это администрировать без нормального ИДЕ, без систем автогеренации документации, без ограничений видимости…

Или простую прикладную лапшу на бейсике с номерами строк, и без комментов напишите :) Помню как у меня пару месяцев ломка была, когда я от GOTO отучался. Но я то понимал, что тут или переучивайся, или умри как программист. Но некоторые нашли третий путь — пошли преподавать :)
Абсолютно с вами согласен. Я сейчас занимаюсь тем, что переписываю одну 6000-строчную Fortran-овскую процедуру на C#. И, о если бы вы только знали, как же я радуюсь каждому комментарию. Разумеется, что для каждой платформы, для каждой методологии, для каждой конкретной ситуации нужны свои стандарты кодирования, нужен свой взгляд на то, что считать правильным кодом. В своей статье я ориентировался на языки высокого уровня, на которых пишутся большие проекты. И при таком раскладе, мне думается, у меня весьма правильный взгляд на комментирование.
Да я конечно это понимаю. Понемаю заче нужны коментарии. ну не понимаю зачем заставлять людей коментировать банальные веще такие как присвоение переменных, даже в тех же самых бэйсиковских программах. Одно дело пояснение переменной, у которая имеет облась видимости во всей функции.
Разве вы коментировлали нэймспйэсы, переменный итерирования, инкремент, декремент?
Помойму вот такое как раз показывает не опытность преподователся. Ведь все мы с вами айтишники, а это подразумевает неприрывное развитие в сфере деятельности.
Разве вы коментировлали нэймспйэсы


Ага…
using System.Drawing;  // for Point structure only! No other graphic functions used
ну не все же? а только исключительные ситуации
using Point = System.Drawing.Point;
А комментарий убрать за ненадобностью.
НЛО прилетело и опубликовало эту надпись здесь
Чего «столько всего»? Экономия на спичках?

Если в файле много «юзингов», то это запашок, да. Но ставить уменьшение их количества как самоцель — глупость.
«Повторное использование кода, не не слышал»
НЛО прилетело и опубликовало эту надпись здесь
Если объект устроен, как точка, выглядит, как точка и крякает, как точка — он ещё логический или уже графический? Даже если в этой программе он не будет использоваться в качестве координат точки на картинке (из-за отсутствия в ней картинок)?
НЛО прилетело и опубликовало эту надпись здесь
Если эта точка потом используется в интерфейсной части, как та самая System.Drawing.Point, то почему бы и нет? Зачем потом городить огород с преобразованиями типа? Медленно, непонятно и, главное, лень )
Почему нет, если абстракция подходит и формой, и содержанием? Хотя немного вы правы — некрасиво, что такая абстракция в графике, а не в какой-то коллекции абстрактных геометрических примитивов.
Иначе пришлось бы изобретать велосипед — писать такую же структуру с тем же смыслом. Если бы это был C или C++, я бы в большинстве случаев оставил int[2]. Но в C# это уже объект, а это дорого…
С другой стороны, в своей структуре я смогу потом и заменить тип полей, и добавить что-нибудь специальное… Так что, в общем, смысла нет. И вообще всё зависит от конкретной ситуации.
Насчет комментирования неймспесов вспомнился ещё вариант комментариев в конце блоков, помечающий то, какой блок закрывается.

Актуально даже в автогенеренных программах. И когда листинг занимает более одной страницы.

while(flag) {
  if(cond) {
    doOp();
  } // while flag
  doAnotherOp();
} // if cond
А комментарии здесь специально перепутаны?
Ой =)
Действительно полезный приём, чтобы не запутаться в веренице закрывающих скобок какой-нибудь WndProc.
Оно особо полезно в кодогенераторах, чтобы выхлоп получался хоть чуточку читаемый. Или если самому писать FSM.
FSM? Flying Spaghetti Monster? Finite-state machine?
Учитывая контекст — второе) Хотя идея написать первое заставляет пофантазировать.
Ох. Теперь я понял смысл комментария.

Был уверен, что имелось в виду «если самому писать лень» :)
Ужасный приём. К какой конструкции относится закрывающая скобка может показать вам IDE, когда вы ставите каретку у закрывающей скобки или подводите к ней курсор мыши (кусок кода с соответствующей синтаксической конструкции всплывает вверху экрана, если он не помещается в области просмотра). Что касается комментариев у закрывающей скобки, то пользоваться ими для изучения кода нельзя, т.к. они не влияют на исполнение программы (и, соответственно, доверять им нельзя).
Среда среде рознь. У меня никакой кусок кода нигде не всплывает. Если щелкнуть перед скобкой — да, парная подсветится, но ведь гораздо удобнее просто пробежаться по коду глазами, чем делать какие-то лишние движения мышкой.
Если Вы просто пробегаетесь по коду глазами, то Вам не потребуются подобные комментарии (достаточно будет хорошо оформленного кода — с отступами). Но в любом случае, принимать подобные комментарии во внимание нельзя, т.к. к исполнению кода они не имеют никакого отношения. Это хоть понятно?
Иногда это является конструкцией языка и доверять можно.
Пример — pl/sql.

В конце хранимки в пакете может стоять «end;» или «end procedureName;» при эом имя валидируется при компиляции — очень удобно потом при большом количестве хранимок, не приходится полагаться на совесть того, кто ставил отступы.
Это не комментарии, а как Вы заметили — конструкция языка. Здесь речь идёт о комментариях. Что касается отступов — используйте автоматическое форматирование кода (если мне не изменяет память, то эта возможность есть в PL/SQL Developer).
Если Вы просто пробегаетесь по коду глазами, то Вам не потребуются подобные комментарии (достаточно будет хорошо оформленного кода — с отступами).

Есть ситуации, в которых потребуются. Например, если Вы когда-нибудь писали под WinAPI, то должны знать, что даже если мастерить над ним собственную обертку, огромных свитчей на несколько экранов там не избежать, и отступы не сильно упрощают дело.
Во-первых, кроме IDE ещё существуют просто текстовые редакторы.

Во-вторых, иногда приходится редактировать код удаленно, имея под рукой, как максимум, vim (и то, если повезло). Без своего привычного окружения, без плагинов и прочих радостей. В случае vim'а отчасти спасает code folding.

Во-третьих, разные IDE имеют разный функционал. Особенно обделены в этом плане коммерческие IDE для SoC, DSP и прочей embedded радости. Может, конечно, там за последние пару лет внезапный прогресс, которого не было до этого добрых полтора десятка лет… Более чем подсветки синтаксиса многие даже не имели (например, переход к заголовочному файлу, объявления/имплементации функции). И это среды, которые зачатую стоят более 500 USD не считая железа.
Использование текстового редактора вместо IDE лишь снизит удобство взаимодействия с кодом. Комментарии подобного рода, как я уже писал выше, к исполнению кода никакого отношения не имеют, поэтому нельзя использовать их для того, чтобы понять как работает код (это породит ошибки).
Наличие более двух уровней вложенности уже замыливает взгляд.

Комментарии такого рода нужны не часто. Сходу приходят в голову: автогенерированный код (где к минимализму отнюдь не стремятся и ошибки комментирования маловероятны) и сложные управляющие структуры, которые занимают больше одного экрана (например, блоки switch или if/else if/else в выборе состояния FSM).

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

И Вы предлагаете замылить его ещё больше с помощью комментариев?

Комментарии такого рода нужны не часто

Ещё раз: комментарии такого рода не нужны. Повторяю: при чтении кода Вам необходимо понять последовательность исполнения кода. Комментарии на последовательность исполнения кода не влияют. Что тут непонятного?

Сходу приходят в голову: автогенерированный код (где к минимализму отнюдь не стремятся и ошибки комментирования маловероятны) и сложные управляющие структуры, которые занимают больше одного экрана (например, блоки switch или if/else if/else в выборе состояния FSM).

Ещё раз: используйте предназначенные для этого инструменты (IDE), а не засоряйте код.

Вполне очевидно, что они могут устареть. Но если у Вас устаревшие комментарии в коде — это другая проблема, несомненно требующая решения.

Это не другая проблема, это проблема, которую порождает Ваш подход.
Ещё раз: комментарии такого рода не нужны. Повторяю...
Я Вашу позицию услышал и принял к сведению. Не стоит старательно делать вид, что Вас не понимают и общаться с другими, как с людьми, страдающими олигофренией.

Ещё раз: используйте предназначенные для этого инструменты (IDE), а не засоряйте код.
А вот меня, видимо, не услышали. Есть приличное количество IDE, которые умеют только подсветку синтаксиса, сборку проекта и отладку. У некоторых ещё автоматический отступ для новых строк после { есть. Aus.

Это не другая проблема, это проблема, которую порождает Ваш подход.
Это системная проблема. Как максимум, она может незначительно усиливаться в случае неправильного применения подхода, о котором я поведал. Но только при наличии самой проблемы.

Каждый имеет полное право оставаться при своём мнении. Стоит прекратить дискуссию, пока она ad finem не превратилась во флейм.
Я Вашу позицию услышал и принял к сведению. Не стоит старательно делать вид, что Вас не понимают и общаться с другими, как с людьми, страдающими олигофренией.

Я действительно подумал, что Вы меня не поняли, т.к. я обращал внимание на важность и первичность именно данного аспекта (первичность кода над редактором).

А вот меня, видимо, не услышали. Есть приличное количество IDE, которые умеют только подсветку синтаксиса, сборку проекта и отладку. У некоторых ещё автоматический отступ для новых строк после { есть. Aus.

Я Вас услышал, но расценил Ваши слова как призыв к тому, чтобы подгонять код под редактор в ущерб качеству кода.

Стоит прекратить дискуссию

Как скажите.
Насчет комментирования неймспесов вспомнился ещё вариант комментариев в конце блоков, помечающий то, какой блок закрывается.

Мне в этом плане PHP нравится: есть краткий «сишный» синтаксис с фигурными скобочками и длинный «альтернативный» синтаксис с if/endif, foreach/endforeach. Жалко, что в C# такого нет — очень было бы к месту при написании кодогенрации на T4, например: вечно получается какой-то нечитаемый лапшовый код, который не то, что читать — писать страшно.
в пыхе это не с проста — это последствие «шаблонности»:
<?php if(something): ?>
бла бла бла, продолжаем мегашаблон
<?php endif; ?>

попытка засунуть сюда фигурные скобки приводит к мракожути
Кодогенерация как раз зачастую на шаблонах и основывается
НЛО прилетело и опубликовало эту надпись здесь
Очень плохой вариант, использовал раньше в своем опен сурс проекте, потом отказался. Там проблема такая же как в пункте где указано что коментарии врут. После рефакторинга часто бывало так как у автора, коментарии несоотвествовали.
Я много чего понял когда поддерживал несколько лет большой проект. Часто принципы основаны на желании кодить в стиле — написал -> забыл. Но как только начинаешь поддерживать код, то все рюшечки и красатульки начинают раздражать. Всякие отступы, коментарии неймспейсов, и т.п.
Как я писал в ветке выше, это удобно в крайне небольшом количестве случаев. В остальных — не нужно.

Удобно в автогенерированном коде, где вероятность ошибки невысока, а читать его может быть будут.

Удобно в сложных развесистых блоках конечных автоматов. E. g. в IDE не предоставляющих нормального функционала.

Второй случай встречается редко. В основном относится к ассемблерам (в которых код имеет плоскую структуру, ergo комментированию надо уделять ещё больше внимания) и C. В коде на Java, Ruby, Python смысла так делать обычно нет.
Не «неопытность» а именно что «отсталость».
Если бы мы жили в двадцатом веке, и я был бы Вашим преподавателем, то я бы тоже заставлял комментировать всё-всё-всё.
Сначала мы привыкаем комментировать всё, потом уже когда появляется опыт, и способность мыслить, тогда мы уже осознанно опускаем комментарии там, где они неуместны.
По опыту скажу — если человек говорит себе, что он будет комментировать только то что нужно, то он не будет комментировать почти ничего. А потом встретит свой собственный код через год. И тогда начнет комментировать всё :)
Я представляю, банальный рефакторинг увеличивается в разы) тк. еще коменты над править.

И тогда начнет комментировать всё :)
ну не скобки и операторы же) получается какое то коментирование ради коментпирование.
Мы сейчас о каком веке говорим?
Я о своем веке говорил) т.к. меня это застало. в начале 5 курса. И удивляюсь как тяжело живется людям которые предерживаются тактики комментирования всего в коде, хотя наверное они не часто рефакторингом занимаются в том смысли котором думаю я.
Нас заставляли строчки вида
{

Комментировать :(
value = twoValue >> 1; // Два знака больше означают побитовый сдвиг вправо
// таким образом мы делим число на два

IMHO здесь вполне себе уместный комментарий. Синтаксис неочевиден для тех, кто не встречал такую конструкцию. Да, в сях и других более-менее низкоуровневых языках это распространенная практика, но очевидна она не для всех. В таких случаях лучше перебдеть, чем недобдеть. Хотя конечно по-человечески это было бы что-то вроде:
value = twoValue >> 1; // Битовый сдвиг. Т.е. делим на два

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

В остальном — да, для сферического проекта всё верно, и к этому стоит стремится. И объяснять заказчику почему тебе блин надо неделю на ревьюв и рефакторинг тоже обязательно :)
Ну, тут возникает вопрос, какой синтаксис считать очевидным. Битовый сдвиг — достаточно известная конструкция, средний программист должен её знать. Если начать комментировать каждый битовый сдвиг, то в коде будет помойка. В данном случае код непонятен не из-за того, что он плохо написан, а из-за низкого уровня читателя — лучше бы ему подтянуть свои знания.
Понятно, что тут нужно смотреть каждую конкретную ситуацию отдельно. Т.е. если мы используем какую-то страшную неочевидную магию на битовых масках, то можно и написать комментарий — ведь неочевидность будет заключаться в сложной синтаксической конструкции, а не в элементе синтаксиса.
P.S. А вообще, современные компиляторы и интерпретаторы всегда оптимизируют деление на два, поэтому писать (twovalue >> 1) особого смысла не имеет. Но это уже совсем другая дискуссия.
Если в данной ситуации важно, чтобы для отрицательных чисел округление шло вниз, то надо не только написать, что это деление на два, но и добавить пример, что (-3)>>1 == -2. А то придут борцы за понятность кода и «улучшат» его, заменив сдвиг на деление. А потом разбирайся, почему индексы за границу массива стали выходить.
А вот для борьбы с такими борцами лучше использовать модульные тесты, как и сказал автор.
Есть ещё люди, которые портируют код на другие платформы.
Для них был бы очень полезен комментарий, зачем использована конструкция, чье поведение зависит от реализации, и что этим кодом хотел добиться автор.

The value of E1 >> E2 is E1 right-shifted E2 bit positions...If E1 has a signed type and a negative value, the resulting value is implementation-defined
5.8.3 [expr.shift] C++11 draft n3242
Я вам больше скажу — в подавляющем большинстве случаев оно не имеет смысл даже если они не оптимизируют. Но это совсем другая история.

На счет уровня читателя — а откуда я знаю какой у него будет уровень? Все хаки должны быть задокументированы. Иначе слишком много нужно держать в голове. А потом там будет не 1 а три… А потом кто-то перечитается теории и заменит эту тройку на константу))) Нет уж. Используешь хак — будь добр его описать. Я не хочу тратить лишние милисекунды своего процессорного времени, чтобы понять что они хотели этим сказать. И переполнения стека от таких вот простейших распознаваний я тоже не хочу. Не использую тройственный оператор выбора, комментирую хаки, и считаю это верным.
А что считать хаком? Битовый сдвиг — вполне распространённая операция. Нормальный программист должен знать синтаксис языка, я считаю. Если я на основе этого синтаксиса делаю какой-то хитрый хак, то ок, я его закомментирую. Но сам синтаксис комментировать не следует. А то вдруг, мой дорогой читатель не знает что такой наследование. Это же не причина перед каждым классом, который наследуется от другого, пояснять общий механизм наследования, как он работает, зачем он нужен и т.п. В конце концов, нужно по каждому конкретному проекту смотреть средний уровень разработчика, который с ним работает.
Битовый сдвиг нормальная операция, использование её для деления — хак, пускай и очень распространенный (хотя теперь реже)
Всё верно написано, даже добавить нечего.
Правда человеку пришедшему из ассемблера понять это сложно.
А я помню как я переживал, когда пхп объявили операцию «GOTO — возвращение».
Но всё обошлось. Старики это переросли, а малыши просто не знали как круто они могли наговнокодить…
Я не хочу тратить лишние милисекунды своего процессорного времени, чтобы понять что они хотели этим сказать


И заставляете тех, для кого это не хак, а идиома, тратить десятки миллисекунд на то, чтобы распознать комментарий, и убедиться, что в нём ничего по делу не написано — только разжевано то, что и так есть в коде. Может быть, лучше уважать читателя, и не считать его дураком?

А что касается замены тройки на константу — приходится так делать…
NewAmp=OldAmp<<SHIFT_OLD_TO_NEW_AMP;
Правда, потом забываешь, как называется эта константа и снова пишешь OldAmp<<17. Хотя, возможно, чтобы сэкономить миллисекунды читателя надо было бы написать OldAmp*131072…
Не нужно смешивать магические константы и давно устаревший хак.
И вообще, если уж передергивать, тогда давайте уж писать
const int CORE_CONST_TWO = 2;
newValue = oldValue / CORE_CONST_TWO;
В данном случае я бы написал «деление на 2», то есть прокомментировал бы (условно) нетрадиционное использование стандартного оператора, основанное на «тайных знаниях» о двоичном представлении целочисленных значений. Но вот что это битовый сдвиг я бы комментировать не стал. Это как написать n = i * i // умножение, хак для возведения в квадрат :)
Это как написать n = i * i // умножение, хак для возведения в квадрат :)


А так?

n = i * i; // мы уверены, что i<46340, так что переполнения не будет. Но честнее было бы d=(double)i*i;
Так нормально.
Все такие примеры зависят от конкретной ситуации. В определённых ситуациях подобные комментарии могут быть оправданы, но правило прецедента тут не работает: не комментировать же теперь каждую арифметическую операцию рассуждениями о переполнении. В таких дискуссиях никогда не встречается прописных правил, которые применяются в 100% сценариях: всегда можно придумать случай, когда общее правило не подойдёт. Но мы сейчас обсуждаем именно общие подходы к написанию программ. И вот в общем случае комментировать умножение необходимости нет.
А так?

n = i * i; // мы уверены, что i<46340, так что переполнения не будет. Но честнее было бы d=(double)i*i;
Если мы уверены, то логичнее перед этой строкой добавить assert(i < 46340), а не захламлять код комментарием.
Во-первых, магическая константа 46340 может быть не понятна. Во-вторых, аасерт на всякий случай в некоторых языках снижает эффективность, особенно в цикле.
Константу-то можно и как-нибудь назвать (POW_2_TO_15_AND_HALF). Но к ассерту всё равно неплохо бы дать объяснение — зачем такая проверка. Особенно, если он не перед этой строчкой, а там, где вычисляется значение i.
Как правило assertions можно отключить для production кода и включить на время отладки/тестирования.
Что же до «непонятности», то разъяснения можно дать в сообщении к этому assertion.
А-ля

assert(i < 46340, "Значение i выходит за границы допустимых значений. При вычислении n произойдёт переполнение разрядной сетки");


Бонусом получим повышение вероятности отловить баг, связанный с неверным значением i. Простой комментарий дать нам этого не может.
В принципе согласен. Я изначально так и хотел написать. Собственно так и пишу. Но тут решил чуть перестраховаться и дописать еще два лишних слова. По опыту некоторая денормализация документации бывает полезной. Т.е. если где-то в сложном месте используется редкий метод или функция, то я лучше два слова про нее скажу, чем потом через год буду лезть в документацию функции или метода и выискивать именно то применение которое тут было в мегабайте документации.
В этом плане крайне полезны in-code documentation (типа JavaDoc, ri/rdoc, стандартных python'овских комментариев, doxygen и пр.).

В этом случае ничего не мешает нажать hotkey для просмотра документации не вылетая из контекста IDE.
В случае языков высокого уровня битовые хаки используются не часто (если не смотреть внутрь какого-нибудь Lucene или Tika) и их комментирование может быть оправдано.
А, например, в разработке на C, да ещё и не на x86 они могут быть вполне обыденным явлением. С другой стороны многие стандартные битхаки любят выносить в макросы: и производительность не падает, и понятность кода на том же уровне.
Мне тут неделю назад посоветовали для оптимизации цикла на пхп развернуть его.
При этом утверждалось, что читабельность кода не ухудшится (мы изначально договорились, что более эффективный алгоритм не будем делать, ибо простота важнее).
на пхп понимаете!
Поначитаются хабра, а потом лезут в нанооптимизацию.
И нет, я не против оптимизации. Я помню как я разработчика пилил, что он под переменную _целый_байт_ оперативки выделил, когда хватило бы и четырех битов. Ну дык у меня там всего 32байта озу было…
В случае языков высокого уровня битовые хаки используются не часто (если не смотреть внутрь какого-нибудь Lucene или Tika) и их комментирование может быть оправдано.

Битовые сдвиги рулят для битовых флагов. Например:

    [Flags]
    public enum DialogButton
    {
        None   = 0,

        Ok     = 1 << 0,
        Cancel = 1 << 1,
        Yes    = 1 << 2,
        No     = 1 << 3,
        Close  = 1 << 4,

        OkCancel = Ok | Cancel,
        YesNo = Yes | No,
        YesNoCancel = Yes | No | Cancel,
    }

Использую практически везде, потому что «хаковые» и «редко используемые» битовые сдвиги в разы более читаемы, чем любое другое представление: степени двойки в десятиричном виде до минимум 16-й степени наизусть знают далеко не все; шестнадцатиричные числа читать тоже не очень удобно. А так — очевидная прогрессия, и битовый сдвиг используется именно как битовый сдвиг (то, что для битовых флагов используются степени двойки — в данном случае наоборот хак).
Это как раз не хаки, а использование по прямому назначению. а вот когда пишут 1 << 1; // умножаем на 2 — это хак.
Битовые операции при работе с битовыми же полями — это необходимость, нежели хак. И они выглядят естественно и не вызывают отторжения.

Использование битовых операций ради вычисления 1/sqrt(x) — хак, который просто необходимо пояснять.

А про шестнадцатеричные числа Вы зря. Они очень удобны и легко читаются, особенно, когда используются регулярно. Но это относится не к высокоуровневым языкам, а к C и различным ассемблерам.
Хорошая статья. Для себя давно выбрала не комментировать. Лучше уж названия методов в несколько слов, так хотя бы по листингу функций класса сразу понятно, какая функция что делает. Ну и TODO, куда ж без этого, особенно когда кода генерируется очень много подряд и какой-то кусок хочется написать потом, когда мысли переведу с того что делаю. Правда, я пишу всегда одна, была бы команда — наверное думали бы…
Я смотрю, что «не комментировать» — это уже круто считается. Ты комментируешь — значит ты лох. Утрирую, конечно. Попытайтесь написать комментарий к методу и когда запнетесь на том, что же метод делает, вы, вуаля, вдруг понимаете, что стоит его переписать чтоб можно было в нескольких словах это описать. Это один из плюсов комментирования. Их много еще.
Отнюдь. Преклоняю голову перед теми кому не лень писать комментарии к собственному коду и очень уважаю этих людей. Если комментарии к месту, конечно. Я же на такое не способна, просто радуюсь, что «это норма» :D

А я вот считаю, что лучше понятный код. (доходчевые имена, уместные абстракции и т.п.), чем не «пахнущий код» удобреный коментариями.
Какое-то это всё детство.
Код часто пишется в спешке, и если остался метод на 300 строк без комментариев — что, у программиста будет оправдание «просто я собираюсь его разбить на методы и комментарии будут не нужны».
Или скажем «хороший код в комментариях не нуждается» — т.е. программист сам для себя решает что он-то уж точно гений и пишет хороший код, значит комментарии писать ему не нужно в принципе.
В общем, все эти доводы чаще всего используют чтобы не делать свою работу качественно, просто потому что «не хочется» или «нет времени».
>>Код часто пишется в спешке
Тут нужно определиться с нашими целями. Одна цель: написать как-нибудь что-нибудь побыстрее, чтобы оно побыстрее начало запускаться — и в продакшн. Тут не до идеального кода, вполне понятно что кривые конструкции программист пытается компенсировать комментариями, которые можно написать проще и быстрее. А другая цель: написать хороший качественный код, который приятно читать и поддерживать. Обратите внимание, что я опубликовал пост в хабе «совершенный код». Да, совершенный код — это весьма относительное понятие, но всё равно нужно к нему стремиться.
Вы это серьёзно? Целью в промышленной разработке ПО является получение прибыли. Есть масса проектов где заказчик давит по срокам и придирается к каждому часу — но это же не значит что такой заказчик плохой и работать с ним не надо. В разработке коробочных продуктов такое тоже бывает — срочно нужно успеть к выставке, показу крупному заказчику итп.

В этих условиях вы быстро забудете про «идеальный/совершенный код», но если вы ответственный человек, то будете искать способы повышения качества без потерь времени. Комментарии это и есть один из способов повысить качество без больших потерь времени. Безответственный человек найдёт десяток отговорок чтобы работать меньше. В том числе часто слышу довод «комментарии не нужны, потому что код должен быть хорошим».
> Но ещё лучше бы было сделать именованную константу, из названия которой всё было бы понятно. Например, так:
> private const int SecondsInHour = 3600;

я в свое время стал придерживаться правила — использовать именованные константы, только если они в коде потом встречаются более одного раза. иначе проще уж написать комментарий // справа
Тут беда в том, что когда вы так сделаете один раз, а через полгода вернётесь в этот же файл дописать другой метод, где тоже используется это число — не факт что вспомните, что оно где-то уже написано. Можно, конечно, каждый раз перед написанием искать число по всему проекту (ага, а еще отсеивать такие же числа, имеющие такое же значение, но другой логический смысл), но так получится ещё дольше, чем просто заводить именованные константы.
Полностью с вами согласен. Если речь идёт о большом проекте, то лучше с самого начала соблюдать подобный подходы. При развитии кода нередко такие одноразовые комментарии выливаются в большое количество головной боли через несколько месяцев.
Впрочем, опять-таки всё зависит от проекта. Если у вас python-скрипт на 20 строк, рост которого особо не предполагается, то там константу можно и не заводить.
Именованные константы не спасут вас от возвращения к коду через полгода с забыванием того что там было написано.
У вас в каждом классе появится своя
private static final int SECONDS_PER_HOUR = 3600;
private static final int SecondsInHour = 3600;
private static final int SecsPerHour = 60 * 60;

Ну, это плохой подход. Если у вас много классов оперирует со временем, то, возможно, стоит переписать код так, чтобы основная логика работы со временем была бы сосредоточена в каком-то одном классе. Тогда эта константа будет появляться в коде один-единственный раз.
Для любого тезиса о подходе к программированию всегда легко привести пример, когда в дальнейшем плохие разработчики превратят этот подход в плохую практику. Но я настаиваю на позиции, что лучше бы выработать такой подход к программированию, чтобы плохих практик в проекте появлялось поменьше.
Я не говорю — плохой подход писать именованные константы или хороший.
Я лишь сказал, что само по себе слепое следование правилу правило «использовать константы всегда» мне лично кажется нелогичным, потому как захламляет код в случае однократного использования константы и не спасает от «забывания»

что вы скажете увидев в чужом коде строчки типа
private static final int MILLIMETERS_PER_METER = 1000;
private static final int CENTIMETERS_PER_METER = 100;
private static final int METERS_PER_KILOMETER = 1000;
и потом оперирование этими константами например для расчета протяженности маршрута?
чем константа 1000 хуже константы 3600? Обе некруглые, так как не степени двойки :)
Ок, согласен, всегда — не нужно.
Мой тезис заключался в том, что если вы всё-таки решили написать комментарий к магическому числу, то почему бы не заменить его именованной константой. Вряд ли вы будете комментировать константу в коде типа kilometerAmount = meterAmout * 1000. В каждом конкретном случае нужно смотреть насколько магическим является используемое число и насколько очевидным является его использование.
что вы скажете увидев в чужом коде строчки типа

Порадуюсь за автора. Что у него хватило тщательности правильно работать с константами. Иначе, увидев где-то умножение на 16.666667, мне пришлось бы соображать, что это перевод скорости из километров в минуту в метры в секунду (или из метров в час в миллиметры в минуту?). А если там METERS_PER_KILOMETER_D/MINUTES_IN_HOUR_D — ситуация будет немного понятнее.
НЛО прилетело и опубликовало эту надпись здесь
В прикладном программировании редко считаются круглыми степени двойки, а не десятки. Но вообще согласен — в константы предпочитаю выносить пускай статические, но параметры алгоритма, а не все подряд числа из формул, хотя бывают и исключения, но они скорее интуитивные чем формализованные.
А через полгода вы вспомните, как называлась эта константа? И была ли она вообще? Хотя с числами, имеющими то же значение, но другой смысл — та ещё проблема. Особенно, если есть функция, в которой эта константа имеет одновременно оба смысла (возникшая в результате применения DRY — зачем писать две одинаковых функции, одна из которых работает с секундами времени, а другая — с угловыми секундами?)
Я считаю, что константам нужно давать понятные очевидные названия и размещать их в адекватных для этого местах.
Понадобилась мне какая-нибудь логика работы с обычными секундами — я полез в класс TimeHelper. Понадобилась мне логика работы с угловыми секундами — я полез в класс AngleHelper.
Я не говорю, что очень легко спроектировать систему так, чтобы размещение любой функциональности было безумно очевидно. Но это то, к чему нужно стремиться.
С очевидными названиями проблема. Например, мне не так давно понадобилось дать имя константе 1296000. Как её назвать? ArcSecondsPerRound? AngularSecondsPerTurn? SecondsOfArcInCircle? Какое имя не дашь — всё равно при каждом использовании придётся лезть в класс — как он называется в этом пректе? AngleHelper? AngularHelper? AngularConstants? просто Const? — и искать там нужное название. Конечно, IDE со своими подсказками помогает, но даже это заставляет отвлекаться на лишние секунды времени (и переключать контекст с и без того сложной задачи).
Ну, я и не говорил, что программирование — особо лёгкое занятие. Да, есть проблемы. Да, их нужно решать, Да, очень непросто построить архитектуру так, чтобы всегда было очевидно где посмотреть ту или иную вещь. Авторы замечательных книжек, которые я привожу в начале статьи, уделяют очень много внимания тому, как лучше выбирать правильные именования. Но мнение «мне слишком сложно придумать правильно название» не является аргументом в пользу того, чтобы спокойно раскидывать по всему коду числа вида 1296000 и считать, что всё хорошо.
Лично у меня есть класс Constants в нём навалены вообще все константы проекта, которые теоретически могут быть использованы более одного раза. Если у меня где-то в классе встречается 1 час, то это обычно 60 * 60 * 1000L, ибо миллисекунды. И пусть оно лежит отдельно, константа ни кому не мешает, а код украшает. А если я завтра решу поменять на два часа, то будет это сделать легко и просто…
Факт. Заменим «MILLISECONDS_PER_HOUR» на 2*60*60*1000L.
ой, жееесть…
>Лично у меня есть класс Constants в нём навалены вообще все константы проекта

У Вас, видимо, сильно маленький проект. В проекте среднего размера их будут тысячи, заколебётесь искать.

Константам место в классе, к которому они относятся.
TimeHelper::MILLISECONDS_PER_HOUR — вот так.
Если комментариев много и не по делу, я просто меняю их цвет в своей любимой IDE на цвет близкий к background, таким образом глаза перестают за них цепляться.
Ну и всегда приятно, когда есть комментарий к классу описывающий его назначение в системе, сам их тоже пишу.

Комментарии в самих методах/логике пишу только если используется workaround, обходный путь, чтобы было понятно почему-то так странно сделано.
Ещё периодически встречаются вполне обоснованные комментарии (со ссылками на тикеты в багтрекере) запрещающие изменения фрагментов кода.
Особенно это актуально, если нет нормальных тестов или они чрезмерно сложны. По сути, комментарии поясняют неочевидные моменты, зависимости и решения.
Да, я упоминаю подобные комментарии в статье. Это вполне нормальная практика, предотвращающая ситуации, когда один из разработчиков по неосмотрительности испортит критически важный фрагмент кода.
Противникам комментирования всего подряд полезно почитать код ядра, например
Я зачастую ставлю комментарии для визуального разделения кода на блоки, т.е. сам комментарий не несёт смысловой нагрузки, по сути дублирует название функции, но позволяет быстрее зацепиться взглядом, ведь комментарии хорошо видны при подсветке синтаксиса.
а функции у вас не выделяются? В нормальных редакторах есть навигация по методам и функциям, а уж о IDE я молчу
Иногда не только функции нужно выделить, а и блок какой-нибудь, комментарии дают более заметную визуальную метку. Пользуюсь Geany, это простенькая IDE, хотя с помощью плагинов можно сделать и не совсем уж простую.
Иногда вставляю в код комментарий с описанием использованного алгоритма, если это что-то очень не тривиальное, типа интерполяции карты высот по нескольким известным точкам. В коде, решающем математические задачи далеко не всегда понятно, что делает та или иная функция из 3х строк, если не знаешь, что там должно происходить вообще.
1. Не нужно прыгать из крайности в крайность.

2. Константы принято писать заглавными буквами для наглядности.

3. Мне очень нравятся комментарии в AngularJS. Всё, что можно выразить в коде — оно в коде. А пояснения выбора такого варианта — в комментариях. Ну и документация автоматически строится из комментариев.
Константы принято писать заглавными буквами для наглядности.

В разных языках разные стили кодирования. В C#, например, SCREAMING_CAPS не используются нигде (если следовать стандартам).
В некоторых языках ещё и от типа констант зависит. Например, в Ruby обычные константы именуются caps'ом, а константы типа класс — camel case.

Но это соглашение, т. к. с точки зрения синтаксиса всё, что начинается с заглавной, — константа.
Есть такой интересный ученый — Непейвода Николай Николаевич.
Он сформулировал короткий и четкий ответ на этот вопрос: комментировать нужно «призраки» и «подпорки».

Подпорки — (ЕСТЬ В КОДЕ, НЕТ В ТЕОРИИ) это отклонения от основного случая алгоритма; то что присутствует в коде, но отсутствует в словесном описании сути работы функции
* отклонения от теорем, на основе которых строится код
* дурацкие крайние cлучаи
* учет несовершенства работы используемых внешних функций, подсистем

Призраки — (ЕСТЬ В ТЕОРИИ, НЕТ В КОДЕ) это знания, заложенные в алгоритм; то, что есть в теории, на основе которой был построен алгоритм, но отсутствует явно в коде.
* математические теоремы; например в RSA алгоритме заложена формула a^(phi(n)) === 1 mod (n) и нужно в коде в комментариях написать ссылку на эту теорему и случай n=p*q.
* инварианты в циклах
* то, о чем полезно знать при чтении кода, но что никак в этом коде не отобразилось, так как является абстракцией более высокого уровня, нежели код


Он этому учил студентов в Ижевске
Нашел текст в викиучебнике, исходный вариант которого написал Непейвода. Там есть что почитать любителям философии от IT.
>>>Но если в проекте всё-таки возникла потребность описать для метода примеры возвращаемых результатов, то почему бы просто не сделать соответствующий Unit-тест?

Можно совместить
Если используется язык со слабой типизацией, то типы приходится прописывать в комментариях.

function readFile(file,buffer,callback)

Без комментариев потом придётся перелопатить весь код функции, просто чтобы понять — что, чёрт возьми, должно передаваться в качестве buffer. Да и file — это имя файла (строка) или же какой-то дескриптор? А callback — сколько у него аргументов и какого они типа?
Языки типа C# или C++ конечно же лишены подобного недостатка, там всё понятно с первого взгляда и без комментариев.
Не со слабой, а с динамической. Вообще же в такой ситуации лучше вставлять assert'ы хотя бы для простейших случаев. Что делать с функциями — не знаю, наверное без комментария тут не обойтись.
Часть проблемы снимается более подробным именованием: file_name и file_descriptor. А часть — в комментарий, который далее пойдет в автогенерированную документацию…
Есть еще пара моментов:

1. Несмотря на отличное знание английского у подавляющего числа программистов (даже не знаю, сарказм это или нет) — он не является родным. И «чтение с листа» затрудняет разбор каждого английского словосочетания. Программирование на русском же пока невозможно (нет нормальных языков). При комментировании английского кода русские комментарии со склонениями, окончаниями и т.д. можно считать как минимум переводом.

2. «Комментарии, которые содержат код»
Вы противоречите сами себе. Если первоначальный разработчик может удалить эти комментарии и потом найти их в репозитарии, то его преемникам точно так же не будет никакого труда удалить все предыдущие комментарии кода и в случае чего восстановить их из репозитария.
И вообще, все, что можно сделать автоматически — удаление комментариев, форматирование кода и т.д. — не должно беспокоить ни разработчиков, ни идеологов кодинга.
Программирование на русском же пока невозможно
Вообще в языках с поддержкой Unicode, например в C# ничего не мешает называть переменные на русском языке:
var счетчик = 1;

Ну и не стоит забывать, что человек, комментирующий код на русском языке, должен быть готов, что завтра его уволят за непонимание комментария на китайском.
НЛО прилетело и опубликовало эту надпись здесь
Ну так можно, но не нужно :-)
В первую очередь раскладка.
Даже в 1С часто приходится переключать раскладку ради некоторых символов которых нет в русской раскладке.
К остальному быстро привыкаешь. И даже параллельно писать в разных проектах на русском и английском это не сложно. А вот с раскладкой постоянно мучаешься.
НЛО прилетело и опубликовало эту надпись здесь
Русский язык кардинально отличается от английского. Это падежи, окончания и т.д. И еще раз повторю, нет ни одного языка программирования заточенного под русский.

Допустим метод «getDog» на русском будет звучать как взятьСобакУ, но Dog — собакА. В таком простом примере переводишь с лету, но некоторые методы могут и 4 и 5 слов в названии иметь и переводить их порой достаточно трудоемко. А чтобы нормально Называть такие метода нужно вообще владеть английским на достаточном уровне.

Поэтому считаю, что комментарии на родном языке необходимы там, где нет очевидного и мгновенного перевода с английского.
Я бы ещё добавил к списку:
1. Комментарии, которые содержат дословный перевод названий функций и переменных с английского языка на родной. Например:
/**
 * Удаляет файл
 */
function deleteFile($path){}


2. Использование комментариев в качестве влияющих на исполнение кода конструкций. В PHP получили распространение так называемые теги (аннотации) в doc комментариях. Этим грешит, например, PHPUnit (аннотации @backupGlobals и т.п.):
/**
 * @backupGlobals disabled
 */
class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @backupGlobals enabled
     */
    public function testThatInteractsWithGlobalVariables()
    {
        // ...
    }
}

Ко всемe прочему, комментарии удаляются интерпретатором PHP, если он работает в связке с ускорителем — поведение кода в таком случае изменится.
А что делает ускоритель в тестовом окружении? Или что делает пхпюнит на продакшене?
Во-первых, правилом хорошего тона является идентичность сборки PHP у разработчика и на продуктиве. Во-вторых, почему Вы решили, что тесты не могут быть написаны для запуска на продуктивном сервере (для периодической проверки его работоспособности)?
Во-вторых, почему Вы решили, что тесты не могут быть написаны для запуска на продуктивном сервере (для периодической проверки его работоспособности)?
Тогда это уже ни разу не unit-тесты. И они, скорее всего, уже не должны использовать фреймворк unit-тестирования для исполнения.
На самом деле mkharitonov во многом прав, я сам стараюсь выносить такие конструкции в код, а не в комментарий, но это исключительно из читабельности. К примеру утверждения в комментариях вполне уместны, ибо помогают автогенерации тестов.
Сильно зависит от языка. В той же Java валидация данных вполне может описываться в аннотациях, которые не оказывают на непосредственную работу кода, но используются фреймворком валидации.
grossws, я бы сказал, что PHPUnit это в первую очередь фреймворк для автоматизированного тестирования, а не исключительно для модульного тестирования.
Я с ним не знаком, из названия считал, что он более-менее совпадает по функционалу с остальным семейством xUnit (Java JUnit, Ruby Test::Unit, Python unittest, .NET NUnit и т. п.), которое предназначено для unit-тестирования.

Я прекрасно понимаю, что ничто не мешает запустить тест в production-окружении, запустив в нем TestRunner.
Основная функциональность заточена под юнит-тесты, но есть инструменты и для других видов тестирования.
Вообще, я плохо представляю чем фреймворк для модульных тестов должен принципиально отличаться от фреймворков для других видов автоматизированного тестирования кода (ведь во всех случаях всё сводится к тестированию поведения кода в разных состояниях).
Ко всемe прочему, комментарии удаляются интерпретатором PHP, если он работает в связке с ускорителем — поведение кода в таком случае изменится.

Проверяли? Я однозначно не скажу, но в общем на это не похоже. Ускорители внедряются в процесс формирования байт-кода, но привязка к исходникам остается. Хоть «ручками» их анализировать, хоть через отражения.
У eAccelerator была такая «фича».
Хорошо, что я им не пользовался практически :)
Если честно, то я это сказал, основываясь по большей части на информации из обсуждений, которые мне вспомнились (каюсь). Сейчас проверил вызов функции ReflectionClass::getDocComment в PHP 5.3.18 + APC 3.1.13 — работает. В eAccelerator теперь доступна опция "--without-eaccelerator-doc-comment-inclusion" и по умолчанию DOC-комментарии теперь не удаляются из внутренней структуры (и доступны для доступа из кода). По поводу других ускорителей и различных ситуаций в APC и eAccelerator не знаю.
Согласен с автором. Часто умиляют описание действий в комментариях типа:

// блин, так хочется спать, но я все равно фигачу тут
// потому что утром дедлайн, а у меня и конь не валялся

Но все же в некоторых случаях, когда берешься дописывать начатое кем-то, либо просто дорабатывать что-либо, открываешь код и думаешь «Господи, почему ЭТО никак не закомментировано??» В таких случаях хочется кому-то навалять, и обычно под раздачу попадает кот.
Знаете что смешно? Что программисты на самом деле не любят писать комментарии, и не писали, пока их не научили. Потому что любой код кажется очевидным, когда его пишешь. И нужен большой опыт и самокритичность, чтобы понять, что это не так. А значит совет «писать самодокументирующийся код и не писать комментарии» возвращает к истокам. Джуниор просто бросит писать комментарии, он ведь не знает, что он джуниор, а код метода на 100 строк и так понятный.
А если вы внимательно читали Макконнелла, то должны были заметить, что он предлагает использовать комментарии в процессе написания кода, как псевдокод, заменяя по ходу блоками настоящего кода (можно и не заменять, если не выделяете в метод). А это вполне себе использование комментариев.
Ну и нельзя не заметить, что далеко не всегда код выходит сразу идеальным (или вообще когда-нибудь), так что такая категоричность в заголовке вообще не для реальной жизни. Всегда будут неочевидные места в коде, которые просто нужно комментировать.
Последнее время ловлю себя на мыслях, что в отношении комментариев формируется примерно такое мнение. Пишу больше для себя, на любительском уровне. Но замечал, что когда пишу комментарий, думаю о коде, то получается примерно такие же по «полезности» комментарии, как приведены в заметке. :)

Сейчас у меня уже сложилась некая практика, что комментариев почти не ставлю, чтобы не тратить время. Но иногда к коду нужно вернуться, чтобы поправить его. И если я с первого раза не вспоминаю, почему функция у меня работает именно так, то тогда пишу к ней уже комментарий.
Комментарии, которые повторяют код
Комментарии, которые поясняют синтаксис
Комментарии, которые поясняют стандартные классы
Замечу, что у комментариев из этого раздела имеется своя ниша — примеры программ. Вероятно, потому студенты порой так и комментируют, что в учебниках все примеры кода такие (и последнее правильно).

Комментарии, которые поясняют константы
Иногда в коде больше констант, чем строк кода. Если строки кода еще и довольно широкие, то такие комментарии становятся неплохой альтернативой именованных константам. Хотя чаще всего такой код означает, что его писал математик или специалист в другой области, отличной от программирования.

Комментарии, которые содержат примеры использования

Но если в проекте всё-таки возникла потребность описать для метода примеры возвращаемых результатов, то почему бы просто не сделать соответствующий Unit-тест?
Потому что написание комментария с примером использования не выбьет программиста из потока, а написание Unit-теста — может и выбить. Хотя, конечно же, такие комментарии есть технический долг.
Согласен с автором. Сам считаю, что код должен быть self-explanatory и комментарии должны быть скорее исключением. И это касательно комментариев к методам и классам, inline комментарии вообще не должны быть.
Всё должно быть в меру.
Достался мне как-то один класс, который надо было чуток допилить под наши нужды. И исправить несколько небольших недочетов. Класс синглтон.
В нем было три публичных метода и… 86(!!!!) приватных методов, большая часть из которых (думаю штук 80) содержали по 1-5 строк кода.
Класс сопровождался двумя примерами применения с двумя-тремя строчками комментариев, док-комментарием к классу и публичным методам, и ни единого комментария внутри.

Я пока не нарисовал блоксхему вызовов, попутно перемещая код из вспомогательных методов в места их вызова, да не полистал спецификации используемых протоколов — не разобрался.
НЛО прилетело и опубликовало эту надпись здесь
А каждый метод имел читаемое наименование, полностью соответветствующее его задаче? Остальные «правила хорошего тона» были соблюдены?
НЛО прилетело и опубликовало эту надпись здесь
и все кроме первого метода будут несамостоятельными

Что вы понимаете под самостоятельностью?

гибкость теряется

Какая гибкость? А она нужна?

еще всю эту цепочку вызовов надо как-то отслеживать

Зачем ее отслеживать? Часто если вам что-то надо отследить, значит, у вас более высокая связность (coupling), нежели надо (особенно это касается связанности по времени, «этот метод надо вызвать после того, а не наоборот»).
НЛО прилетело и опубликовало эту надпись здесь
Возможность пользоваться методом без необходимости обязательного соблюдения каких-то условий, в данном случае независимо от вызов других методов

Для правильно написанного метода это так и есть. То, о чем вы пишете — это временная или логическая связанность, от этого предостерегают и МакКоннел и Мартин.

Возможно что нет, но если вы унаследуйте класс с большим методом и его придется переопределить, то легче будет переписать один метод, чем несколько

Во-первых, вы делаете слишком много допущений: и что от класса можно унаследоваться, и что от него будут наследоваться, и что метод можно переопределить, и что его нужно переопределять…

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

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

но получается что если разбить один метод на насколько мелких, то скорее всего будет просто последовательный вызов методов

Возможно, причина такого результата в том, что изначально ставится цель просто разбить большой участок кода на более мелкие, а не выделить в большом участке кода логически связанные части кода, которые можно будет вынести в отдельные методы (т.е. стоит не просто разрезать участок кода на несколько пропорциональных участков, а «хирургически» вырезать из разных мест данного участка кода логически связанные части).
Как правило, по одну сторону баррикад — самоуверенные джуниоры, имеющие непререкаемую позицию вида «А как же его не комментировать, ведь без комментариев непонятно будет!».

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

Насчет инлайновых комментариев сложно сказать однозначно, а вот по поводу докстрингов к методам и классам — никогда бы не сказал, что они что-то ухудшают. Во-первых, они сильно улучшают автокомплит в IDE, во-вторых, часто помогают быстро понять основное назначение и принцип работы класса/метода, в-третьих, по ним можно автоматически сгенерировать документацию, ну, и в-четвертых, IDE позволяет их сворачивать, если для кого-то они ухудшают читаемость.
Обычно пишу комментарии только в тяжёлых местах (где нетривиальная логика или сильное влияние эмпирических хаков).

Чаще всего комментарий выглядит так:

foo(bar(z)+1); // hack. Workaround for ISSUE-33 (FIXME)
Одним из важнейших чувств человека является чувство меры.
По мне, так комментировать надо всё то, по поводу чего тебя спросили в code review.
Это структура данных, которая называется Хеш-Сет


Прочел эту строчку, мне стало дурно, и я прекратил читать статью. В книгах, которые были приведены вами же, все описанное в статье разложено по полочкам и понятно.
Удивительно, что статья так популярна.
По-моему тема выеденного яйца не стоит. Программисты в большинстве своем не такие идиоты, которые будут писать
int result = 0; // Заводим специальную переменную под результат
int n = elements.Length; // Узнаём длину массива, т.е. количество элементов


Никогда не сталкивался с проблемами, порожденными излишним комментированием, даже если это комментарии как в этом примере. А вот когда в коде лучше бы был комментарий, наоборот сталкивался
Предлагаю обсудить на каком языке уместно писать комментарии! Исходя из того, что переменные и функции обычно называются по-английски, считаю, что комментарии тоже нужно писать по-английски, кроме разумных исключений, конечно. Ведь они, как и названия функций должны быть простыми, чёткими и короткими — это не требует больших знаний английского. Никогда не знаешь, кто будет сопровождать проект, а ещё по-английски, как правило, получается короче.

Я работал в одноий из самыхй больших аутсорсинговых компаний в Беларуси и с комментариями написанными по-русски столкнулся впервые в этой статье, но зато имел дело с проектом, пришедшем к нам от немцев. Не поверите! Весь код был тщательно прокомментирован по-немецки, более того, даже многие переменные и функции назывались по-немецки. Я этим языком я не владел и был мягко говоря возмущён. В нашей компании по гайдлайнам комментарии всеми и всегда писались по-английски, даже для внутренних проектов.

А ещё я поддерживаю мнение, что комментариев в коде быть почти не должно, нужно правильно называть классы, функции, переменные и рефакторить код, как правило в нормальном коде практически всё читабельно.
Сильно зависит от задачи.
Если это некая универсальная библиотека, то да английский язык более уместен.
А вот если это некий сильно завязанный на контекст проект — тут возможно более уместен русский.
Немного холиварный пример — 1С.
Ладно код на русском, его можно поменять на английский. Но вот переменные, классы (я знаю, что там предметно ориентированный язык, а не объектно, ООП это по сути единственное что мне не хватает там, но так будет проще понять) и т.п. лучше называть по русски. Просто в силу того, что терминология очень развитая, и сотни терминов на английском будут сильно путать. Понятное дело, что в другой среде мы будем все равно использовать английские имена или транслит, но уж комментарии так точно лучше пусть будут на русском.

Я это вам говорю как русскоязычный хохол. Проблемы перевода терминологии я знаю с двух сторон. С одной стороны когда заставляли преподавателей и т.п. переходить на украинский, а терминологии или нет, или она никому не знакома. И люди которые отлично знают оба языка толкали такие речи, что Азиров отдыхает… С другой стороны когда привыкаешь, что документы на украинском, а потом тебе вдруг дают бланк на русском, или пытаешься писать документ на русском — материшься.
Я хоть и думаю по русски, но юридический сленг у меня весь украинский, названия организаций, должности, фамилии — всё что пишешь автоматом — по украински. Когда дают бланк в который надо что-то подставить на русском — матерюсь страшно. Понятное дело что это не распространяется на российских контрагентов и договоров с ними…
Ведь они, как и названия функций должны быть простыми, чёткими и короткими — это не требует больших знаний английского.

Краткость — сестра таланта. Немного перефразируя: сложно писать лаконично без потери смысла на языке, который плохо знаешь.

В одном проекте, где были кроме русских немцы и англичане, так там куча проблем была с комментарии и именованием. Изначально решили писать на английском, но как минимум у двух человек (включая меня :) английский был далеко неперфектный и в основном использовали Goggle Translate, что приводило к непониманию., После некоторого числа попыток пришли к схеме:
— кто плохо знает английский, пишет комментарии на родном языке
— кто хорошо знает английский и другой язык, по мере возможности переводит комментарии на английский
— если нет того, кто хорошо знает английский и другой язык, но есть тот, кто хорошо знает два языка (в частности русский и немецкий), то переводит с одного языка на другой (с русского на немецкий), чтобы потом кто-нибудь перевл на английский.
С именованием чуть-чуть по другому — пишем имя на английском в меру его понимания, но комментируем на родном, а потом кто-то переводит имя и обычно удаляет комментарий (или переводит его на английский)
Ну все, закипели народные массы. Комментировать или нет? Как комментировать? Лишний раз призвать на помощь здравый смысл — и все встанет на свои места. Точнее, он как раз не лишний.
Комментировать, но без фанатизма.
Кстати, еще я б так не нападал на школьное программирование и комментарии. ИМХО можно было бы переформулировать пару принципов в нечто общее типа «не комментировать то, что очевидно для тебя, коллег, и того, кто еще возможно будет смотреть код». Если цикл пока неочевиден для школьника (особенно, если мы не просто инкрементим переменную), то лучше уж оставить комментарий, такая шпаргалка при сдаче прогаммы преподу вполне может оправдать «поддрежку» этой строчки кода.

Также это относится к возможно очевидным вещам, лежащим за рамками предметной области: например в силу несовершенства платформы локализация может проникнуть в application-код и возможно придется откомментировать не только «зачем», но и «что на самом деле» делает этот код, т.к. сходу может быть непонятно, что именно важно в этой строчке.

Этого почти всегда можно избежать, но, мне кажется, что иногда проще оставить комментарий, чем рефакторить пол-системы перед релизом, чтобы код стал чуть-чуть читаемей. Через полгода может оказаться, что с десяток таких проблем с читаемостью можно решить одним рефакторингом, который был совсем неочевиден тогда. (но TODO имеет смысл оставить)

Или еще пример: нетипичный для предметной области алгоритм, который проще достаточно обильно откомментировать inline, чем давать ссылку на википедию, по которой через 2 года может лежать абсолютно другой код. Попытка пилить готовый код взятого откуда-нибудь нетривиального алгоритма до удовлетворения чувства прекрасного может вполне стоить рабочей недели, а то и двух.
захламляют непосредственный код, ухудшают его читаемость


Можно в IDE сделать функцию скрытия комментариев. Тогда они не будут мешать тому, кому мешают.
Не IDE едиными.
Вот фигня это на самом деле. Я только в прошлом году заставил себя выбраться из редактора и перебраться в ИДЕ. Считаю что дурак был, что раньше этого не сделал. Хотя да, когда надо что-то по быстрому нашаманить или протестировать, или выколупать значимые куски кода из чужой заготовки, то все равно лезу в фар, но тем не менее — по серьезному писать без ИДЕ — меня уже не заставишь.
С аргументом о том, что многие ИДЕ имеют сильно ограниченный функционал, особенно проприетарные для различного встраиваемого железа я согласен. А с остальным не очень…
Пожалуй, самый эпичный TODO-комментарий:

// TODO make a TODO here
Намёк на костыль, в котором не хочется признаваться. Даже самому себе :D
Комментарии, которые повышают уровень абстракции


Вот хорошая формулировка в принципе для краткого ответа, какие комментарии нужно делать. Тогда частенько окажется, что нужны комментарии видов, которые тут были описанны как не нужные. Так например, совсем не понятно почему не желательны комментарии, которые содержат историю написания. Это как раз тот вид комментариев, которые нужны. Просто их нужно писать когда нужно (а не комментировать простые изменения) и писать их нужно так, чтобы они действительно повышали абстракцию. Все комментарии нужно писать так чтобы они повышали абстракцию. Надо писать не что было изменено, а почему!!! Писать надо не на языке кода, а на языке предметной области. В контролле версий вы делаете общую пометку ко всем связанным изменениям, вида «Клиент такой-то попросил сделать исключение для них такое-то в системе выдачи кредитов так-то». Но для этого вы наделали рефакторингов в ряде мест, поковыряли чужой код (который писали не вы, или даже вы но ему 5 лет и вы давно не помните что его писали вы)… все это обязывает вас написать комментарии, содержащию историю ПОЧЕМУ были сделаны изменения, возможно с перекрестными ссылками того, как влияет изменения в этом месте на другое место кода.

Не сделав это, вы рискуете не понять уже в своем собственном коде причины той или иной конструкции. Через месяц вас отдел тестирования спросит, почему это работает так? А вы и знать не будите причин, а раз так вас попросят вернуть как было… снова сделаете поставку — и вас обругает клиент. А как правило требования клиентов могут быть противоречивы, выполняя одно требование вы легко можете нарушить другое — не видя требования в коде от одного клиента, вы его незаметно меняете. А иначе, вы бы увидели — да старый, устаревший комментарий, не понятно с какой стати тут взялся — но он вам говорит НЕ МЕНЯТЬ пока не дойдет суть комментария с точки зрения требований к коду. Соединив это с новыми требованиями только тогда вы можете сделать рефакторинг, чтобы разрулить противоречивые требования.
Не сделав это, вы рискуете не понять уже в своем собственном коде причины той или иной конструкции. Через месяц вас отдел тестирования спросит, почему это работает так? А вы и знать не будите причин, а раз так вас попросят вернуть как было… снова сделаете поставку — и вас обругает клиент.

А что, использование адекватных систем управления версиями, которые легко отвечают на вопрос «почему так было сделано» — уже не модно?

Собственно, это как раз один из пунктов списка «когда не надо использовать комментарии» — когда вы заменяете комментариями VCS/issue tracker/
Я уже написал, почему системы управления версиями совсем не об этом
Нет, не написали. Хорошая VCS позволяет для любой строчки в коде получить ответ «в рамках какой задачи было внесено это изменение», включая ссылку на эту задачу. Зачем дублировать это в комментариях?
В таком варианте, это переводит вопрос в другую плоскость — с помощью какого средства делать комментарии, т.к. мы договорились, что они должны быть или там или там. Так вот — нет повода отрывать одно от другого.
Поводов более чем достаточно. Комментарии к каждой строчке «это сделано потому, что такой-то написал в письме от такого-то то-то» — это мусор.
это важная информация :) а без него код становится мусором
Нет. Для понимания алгоритма не важно, согласно какому ФЗ он написан.
Это важно для понимания того, что можно изменять в будущем, а что нет.
Поведение кода нельзя изменять без соответствующего PBI, PBI должен анализироваться на импакт, отследить импакт только по комментариям в коде — нереально. Поэтому все равно нужна система управления требованиями, в которой хранится вся эта информация.
Живете в идеальном мире? :)
Нет, занимаюсь улучшением процессов разработки.
Тогда, нужно понять, что система управления требований становится мусором в отрыве от кода.
Нет. Она продолжает выполнять свои задачи (управление и трассировка требований), просто теряется связь с конкретной реализацией.
Это плохой список в таком случае. В том то и дело так формально трактуя этот список — вы будите не правильно пользоваться комментариями в коде :) и никогда не научитесь их писать.
Это вполне нормальный список. И никакой формальности, просто здравый смысл.
Мне в принципе не нравится посыл этой статьи, он говорит когда комментировать не нужно. Правильно же КОММЕНТИРОВАТЬ НУЖНО ВСЕГДА, только делать это нужно по делу… а именно «повышая уровень абстракции».
Как раз наоборот. Комментировать нужно только тогда, когда этого нельзя избежать.
Вот именно такое мнение приводит к тому, что код невозможно сопровождать.
Если вы не можете сопровождать код без комментариев, то это еще не значит, что все остальные не могут сопровождать код без комментариев. При хорошей декомпозиции и именовании в комментировании нуждаются единицы процентов кода.
Это значит, что вы просто не сопровождали :) На этом все, конструктивности диалогов с вами я никогда не видел, и сейчас не имею желания.
Не, не буду доставать и меряться, неинтересно.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий