Pull to refresh

Comments 151

Ну так можно вообще дойти до того, чтобы все функции в одну строку писать. Хотя, доводы в статье в целом разумные.
Доводы в статье в целом отсутствуют. По меньшей мере, я их там не обнаружил. Экономия количества строк кода — не достаточно весомый аргумент, чтобы менять хоть что-то.
1) Краткость — полезное свойство. Если краткость не идет в ущерб удобочитаемости, то стоит однократно переучится. А описанная краткость в ущерб удобочитаемости не идет — после переобучения стало даже лучше.
2) Кроме краткости, еще и унификация. Зачем вводить эти исключения из правил — типа «новый блок с новым отступом, но для public взять на 1 левее»? За счет таких исключений из правил внимание вынуждено удерживать больше данных, навигация по коду становится менее интуитивной — это я сравниваю с тем, что получил после переобучения.
3) Унификация стиля между разными языками программирования. Например, python и С++.
1) Краткость сама по себе, не нужна. Мне так читать неудобно. После переобучения не станет лучше, станет иначе, вам кажется — лучше, мне — нет.

2) Когда сформируете все правила для обоих вариантов — можно будет говорить о количестве правил, пока что нельзя. Хотя, я верю, что в вашем примере правил меньше, но!!! Нельзя для разных вариантов применять одно и тоже, это будет плохо пахнуть для каких-то конкретных множеств случаев. Тут нужно иметь баланс, и у нас с вами он разный.

3) Унификацию можно было сделать по другому.

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

Откуда известно, что не станет? Мне тоже казалось, что начать ставить скобки на той же строке — всегда будет неудобно. А оказалось наоборот. Многие другие люди тоже переобучились, и теперь понимают, что так лучше.

>Когда сформируете все правила для обоих вариантов — можно будет говорить о количестве правил

Можно рассматривать подмножества правил. В частности, 2 vs 1: «после нового блока не должно быть пустой строки» + «но после начала функции должна быть» vs «после нового блока не должно быть пустой строки». Еще одно 2 vs 1: «новый блок должен отделятся дополнительным отступом», «но к блокам области видимости это не относится» vs «новый блок должен отделятся дополнительным отступом».

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

После доводов выше надо еще раз пересмотреть оценку.
Это вы утверждаете, что станет лучше, соответственно и вы должны доказывать. По умолчанию — не верю. Многие люди принимают наркотики, и уверены что так лучше. Другими словами, вы мне говорите, что я должен вам верить на слово, а я не хочу, не хочу и не буду. Математическое доказательство наверное не существует, но хотя бы на исследования авторитетных институтов вы должны бы были ссылаться, а иначе это только ваше мнение, и что так лучше — говорить не можете. Можете только говорить, что для вас так лучше, и для кого-то еще из ваших знакомых…

После нового блока должна быть пустая строка, ибо приколы с git-ом и прочими ребятами. Тут 1-1. Второе согласен. Но нельзя оперировать конкретный подмножеством, к тому-же не репрезентативным, это не научно. Более того, по поводу количества, скорей всего у вас таки меньше правил. Но вы не показали, что меньше = лучше. Я вот например говорил об обратном.

Рановато.
>По умолчанию — не верю

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

>Многие люди принимают наркотики

Так попробовать на одну неделю другой стиль — это не наркотики принять. Хотя привыкание вырабатывается )).

>ибо приколы с git-ом и прочими ребятами

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

Есть много вещей, который стоит попробовать. Это в приоритет в мой приоритет не попало.

Когда-то, не так уж и давно, между прочим, gcc давал warning, если в конце не было пустой строки. Gig в диффах пишет «No newline at the end of file», если такового не имеется.
«Я не обладаю академическими знаниями о нейронах». Как-то пафосно сказал, прошу прощения. Я вообще не обладаю никакими знаниями о нейронах и их свойствах.
>академическими знаниями о нейронах

Академические тут и не нужны. Можно и науч-поп типа Хокинса «Об интеллекте», можно и здравый смысл (как люди вообще чему-то учатся?).

>Есть много вещей, который стоит попробовать

Для программистов вопросы стиля весьма важны.
Все же не надо преувеличивать, «в одну строку» — такого и близко не было, блочная структура в примерах выше сохраняется. Было наоборот — предложение еще активнее выделять блоки (за счет отступов в областях видимости). Также, новые блоки лучше видны, когда дополнительный отступ появляется не после пустой строки, а после заполненной — так глазам легче увидеть, что был дополнительный отступ. И другие предложения — лишь «нормализовать» стиль, избавится от лишней информации.
Как по мне, так код должен быть хорошо читаемым, даже в ущерб краткости. Тут уже поднимался вопрос о переносе открывающей скобки на новую строку: это делать нужно, ибо лучше прослеживается блочная структура кода, имхо.
Блочная структура прослеживается при помощи отступов. Вопрос лишь в привычке.
Совет очень категоричен. Это зависит от языка программирования: C# код с открывающимися скобками на новой строке делает код лучше, а вот такой же подход в JavaScript приводит к нечитаемому коду.
Это результат привычки или объективно предопределено особенностями языка? С js у меня мало опыта, а в C# — так это же официальный стиль от Microsoft того требует, не потому ли «так лучше»==«потому что все привыкли»?
Но официальный стиль не от балды написан. Он основан на опыте других программистов и взвешенных решениях.

А про js: помимо того, что { на той же строке безопаснее, так еще и в коде очень часто встречается {} и визуальнее лучше, когда этот факт «спрятан».
Может, еще повлияло, что в детстве многие на Паскале программировали — а begin на той же строке не попишешь.
Есть те, кто пишет, и не мало :(.
В JavaScript открывающая скобка на той же строке часто объясняется тем что транслятор JavaScript может не правильно интерпретировать код, предположив что пользователь просто забыл указать ';'. То есть безопаснее оставлять открывающую кнопку на той же строке, и также поступать, например, с арифметическими операциями.
кому что, но по мне удобнее не переносит открывающую скобку. имхо.
Java code conventions с вами не согласна. По мне так нужно следовать соглашениям или быть достаточно крутым, чтобы эти соглашения создавать
Для запятых в начале строк (или других операторов в многострочных выражениях) есть ещё одно обоснование — более компактные диффы при добавлении ещё одной переменной/подвыражения.
Так как код читается гораздо чаще, чем diff'ы — то и ориентироваться надо на читабельность кода, а не diff'ов
Многие вещи кажутся действительно неразумными и необоснованными. Другие сам давно использую, например { на той же строке.
А в класс New я бы все-таки добавил variadic templates из С++11.
        template <typename ... Args>
        New (Args ... args) {
            d = new Class(args...);
        }
Visual Studio 2010 не поддерживает variadic templates. Жду VS2012.
ну насчет запятых в начале списка, я пожалуй соглашусь с автором. Читать такой код просто не возможно, ну по крайней мере мне. Никогда не понимал тех кто так пишет.
А что не так с запятыми? Да, с точки зрения пунктуации русского языка — это ошибка, но для С++ запятая такой же оператор, как и +, например. Как лучше:

     int a = very_long_expression1_length1 +
             very_long_expression2_length2__test_lol +
             very_long_expression3_lol;


или же:

     int a = very_long_expression1_length1 
           + very_long_expression2_length2__test_lol 
           + very_long_expression3_lol;


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

Derived::Derived(/* ... */)
    : Base(/* ... */)
    , _x(/* ... */)
    , _y(/* ... */)
    , _z(/* ... */)
{ /* ... */ }


В таком случае мы можем закомментировать инициализацию любого члена поставив в начале строки //.

В случае же

Derived::Derived(/* ... */)
    : Base(/* ... */),
      _x(/* ... */),
      _y(/* ... */),
      _z(/* ... */)
{ /* ... */ }


последний элемент выпадет из правила легкого комментирования строки. И надо будет еще вручную убрать запятую у предыдущего элемента.

Кроме того, так намного удобнее менять местами элементы в списке для большей удобочитаемости: нет опять же того гемора с отсутствием запятой в конце у последнего элемента. Как по мне, первый вариант приемлем и намного удобнее.
Только если будет затронута последняя строка, у которой запятая не такая, как везде. Неужели редактировать ее приходится настолько часто? Вроде чтение исходников происходит намного чаще, особенно в проектах с многими людьми.
Ну во-первых, как я написал в конце, это влияет на простоту изменения порядка элементов в списке инициализации: простой ddp (иначе говоря Cut -> Paste). В случае же запятых в конце, надо следить и поправлять запятые у обмениваемых элементов.

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

Ну а в процессе разработки, разумеется, порядок может еще меняться, и весьма часто.

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

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

>сразу видно не вооруженным глазом — это список инициализации

Эта привычка потом часто распространяется и на другие варианты применения — типа запятых перед параметрами функции, если вызов многострочный.
Но насколько это важно?

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

Эта привычка потом часто распространяется и на другие варианты применения — типа запятых перед параметрами функции, если вызов многострочный.

Абсурд. У меня никуда ничего не распространилось.
>из-за такой вот фигни полночи

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

p.s: а распространенность стиля вообще не показатель.
а распространенность стиля вообще не показатель.

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

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

То есть вы пишите всегда на основе чего-то, что использует ваш стиль? Удивительно. :)
Мой опыт показывает, что во всех проектах стили в чем-то да отличаются. И вообщем-то у проекта должен быть свой coding style, который излагается на wiki-проекта или в pdf'ке. Кроме того, тем кто использует разные стили в одном проекте — руки отрывать надо.

А читать код с непривычным стилем, лишь трата времени и нервов. Хотя второго больше всего. имхо.

Сложно вам наверное в IT. :) Я легко читаю код разных стилей, лишь бы стиль в пределах
одного проекта был одним — это самое важное.
уточнение "… потому что это оператор внутри выражения[, которое обычно пишут в одну строку]".
По результатам изменения рейтинга: «If you want to make enemies, try to change something». Даже если изменения рациональны, менять привычки мало кому нравится. А мне менять привычки понравилось — зная, что работоспособность повысится, это делать легко.
Вы просто не понимаете, что рациональность и комфорт — не одно и то же. Иногда глазу нужно пустое пространство, просто чтобы отдыхать от dense code, заполняющего все остальное.
Отдохнуть взглядом на таком узком пространстве в одну строку?? Если отдых для глаз, то лучше перевести взгляд от монитора. Если же для мозга… Тоже перевести взгляд от монитора?
Отдохнуть взглядом на таком узком пространстве в одну строку??

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

>потоковое чтение текста

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

>«воздух» вокруг «плотных» участков сильно облегчают жизнь

лишь привычка, нет объективных причин для иного. Что, «буфер чтения» перегрузится?
Вы все время говорите о распознавании. Ну окей, говорите о нем дальше, если у вас мозги работают таким образом, то у меня вот нет уверенности, что у меня они работают так же, как у вас.

Ну и рассуждать об этом в этих терминах бессмысленно.

лишь привычка, нет объективных причин для иного.

Привычка — это достаточно объективная причина. Не говоря уже о том, что эстетические критерии в производственном дизайне играют не последнюю роль.
наверное C# придумали индийский программисты, чтобы строк в коде было больше,
сам пользуюсь VB — получается очень компактный и читаемый код
C# — скорее традиции, принятые в команде, перенесли еще с Visual C++ — там аналогичные отступы. Поэтому мне на новой работе было и непривычно, что начинал с VC++. Как до того было непривычно менять CamelCase на javaStyle. И уже после этих изменений понял — привычки меняются, их надо перепросматривать, а к выбору подходить рационально.
Зачем вообще запятые ставить в начало?

Посмотрите, как отличается diff между старой и новой версиями при добавлении строки в конец. В варианте с запятыми в конце в diff'е будет две измененных строки. Если запятые в начале — только одна.

Как бы мелочь, но при мержах разных веток кода бывает приятно.
Уже сколько лет время программиста ценится больше, чем время работы программы. И ничего, все смирились с тем, что программы хотят всё больше памяти и тактов. А уж время работы diff'а — хрен с ним.
Коллега, Вы читаете невнимательно. Никто не обсуждает время работы diff — тем более, что оно определяется количеством входного текста (одинаково в обоих случаях), а не размером репорта. Я повторю ключевое место:

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


Hint: конфликты при мержах разрешает не diff, а вполне себе хомо сапиенс. И жизнь так любопытно устроена, что этот конкретный хомо сапиенс работает в условиях много большего прессинга, чем просто программист, пишущий код. А потому его нужно любить и беречь.
Какое-то уж оооочень притянутое за уши обоснование нового внезапно любимого стиля соображениеми энергоэффективности и увеличением продуктивности.
Про энергоэффективность — шутка же. А продуктивность — нет :) Обоснование не внезапное: раз многие люди переходят на скобки на той же строке, что ими движет? Только ли привычка и случайный выбор привычки? А если нет, не попытаться ли распространить то же правило на другие случаи?

Еще одно — попытка дать дополнительную аргументацию для выбора одного стиля кода для всех. Вдруг существует объективно лучший стиль, на который можно переучится, и не будет проблем?
Круто что шутка, а то я хотел было сравнить оплату счетов в компании за электричество при смене code guidelines.
Половина материала (если не больше) в статье относится к документу типа coding style, который должен быть, если в проекте работает более одного разработчика.
Но когда в разных фирмах разные coding style, хочется выбрать уже какой-то один, чтобы потом не менять привычки. А какой выбрать? Однократно переучится не сложно, но хочется, чтобы после переобучения выбранный стиль был объективно лучше других.
Я за последние 20 лет менял основной coding style точно больше 10 раз и могу заверить, что никакой проблемы в этом нет. Гораздо интереснее ситуация у тех, кто работает одновременно в 2-3 проектах с НЕМНОГО разными coding styles (для аутсорсеров не частая, но и не исключительная ситуация).
Если стили отличаются не сильно, то и в памяти надо держать меньше отличий. Должно быть легче…
Если прийти к универсальному стилю не суждено, то можно хотя бы частично к этому подойти — договариваться по все большему количеству частных случаев, отличия будут уменьшатся…
Если стили отличаются не сильно, то и в памяти надо держать меньше отличий. Должно быть легче…

На практике — наоборот. Переключиться между фигурными скобками «на той же — на следующей» радикально проще, чем между «ставим 4 дополнительных пробела или 2, если оператор продолжается на следующей строке» и т.п.

Если прийти к универсальному стилю не суждено, то можно хотя бы частично к этому подойти


Я в принципе не очень понимаю разговоры про универсальный стиль. Устраиваетесь на работу, читаете местный coding style и следуете ему. Здесь нет никакой свободы обычно. Ну разве что всегда искать работу, где будешь единственным программистом.
>Устраиваетесь на работу, читаете местный coding style и следуете ему

Но кто пишет такие стили? Программисты-тимлидеры. А они могут за свою жизнь попробовать много стилей, и к чему они придут в финале, то и будет очередным стандартом. Поэтому полезно анализировать и выбирать, что лучше. Тогда у большего количества фирм может быть лучший стандарт.

>ставим 4 дополнительных пробела или 2, если оператор продолжается на следующей строке

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

Вам кажется очевидным, что «в финале» они придут к какому-то единому для себя стандарту. К сожалению, это не более чем произвольная догадка. Лично мой опыт мягко говоря не убеждает меня в ее справедливости.

Не лучше ли использовать табуляции? ))

Why not. Вот только я не очень понимаю, как это решает проблему работы с этими двумя конкретными coding styles — даже в предположении, что в обоих разрешены табуляции.
>Вам кажется очевидным, что «в финале» они придут к какому-то единому для себя стандарту. К сожалению, это не более чем произвольная догадка.

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

>я не очень понимаю, как это решает проблему работы с этими двумя конкретными coding styles

Может я что не так понял… Но если вставить одну табуляцию вместо 4 пробелов, и одну табуляцию вместо двух пробелов? Не будут же они вставлять по 2 и 1 табуляции соответственно. А значит и неоднозначности пропадут.
Не потому ли так происходит, что стандарт выбирается больше на основе привычек, а не логического анализа с изменением привычки?

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

Если у Вас есть достоверная информация — можете ею поделиться, всем будет полезно.

Но если вставить одну табуляцию вместо 4 пробелов, и одну табуляцию вместо двух пробелов?

Итак, у нас есть два coding style. Оба разрешают делать отступы пробелами, табуляциями и любым их сочетанием. В некоторой ситуации X первый стиль требует отступ на 4 пробела, второй — на два. Мы не можем изменить сами описанные в стилях правила.

Я вижу, что Ваше решение будет работать ровно в одном случае: если так совпало, что первый стиль приравнивает таб к 4 пробелам, а второй — к 2. Мне это допущение представляется чересчур натянутым.
>Оба разрешают делать отступы пробелами, табуляциями и любым их сочетанием

Зачем?
На хабре уже была эта картинка:
www.emacswiki.org/pics/static/TabsSpacesBoth.png
Если полный переход на табы — никаких пробелов, и один отступ всегда один таб.
В третьем питоне первый же отступ берётся за эталон. Никаких миксов пробелов и табов, либо пробелы, либо таб. Причём если отступ задан пробелами, то размер отступа фиксируется по эталону.
Затем, что в ситуации «делаем отступы только пробелами» Ваш совет вообще теряет всякий смысл. Это я пытался создать ситуацию, когда он хоть как-то применим.
Я и предлагал перейти на табы, чтобы не было таких проблем.
Если бы можно было на ходу менять чужой style guide — проблемы вообще бы не было, не правда ли?
В большинстве случаев да.
Отсутствие пробельной строки между методами, — это ухудшение читаемости кода.
После изменения привычки — наоборот.
Привычка позволяет лишь не напрягаться при чтении менее читаемого кода, а не делаем его более читаемым. Люди, к примеру, программы на J с листа читают и понимают — что не делает его читабельным.
habrahabr.ru/post/149210/#comment_5042696
речь о признаках, которые распознаются мозгом за миллисекунды (анализ областей сплошных цветов, например, начинается еще в нейронах сетчатки, и пустая строка или новый отступ для мозга воспринимаются быстро. А вот подпрограмма действий «прокрутка» — это уже дольше, целый набор рефлексов)
Там есть и ответ, с которым я согласен:
Ну так это рассуждения, а не доказательство.


Но предположим, что Ваши утверждения верны. А именно:

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


Это полностью соответствует высказанному мной выше мнению:

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


Да, обучение (привычка) позволят мозгу легче распознавать это место. Что никак не изменило характеристик самого текста.

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

Напишу еще одно уточнение. Низкоуровневые признаки распознаются автоматически (нейроны шлют сигналы в параллельном режиме), без усилий. Усилия нужны для более высокоуровневой работы — например, синтаксический анализ выражения на J, где надо сопоставлять разные варианты, делать выбор и запоминать его («а это значит параметр вот той функции»). Вон те пустые места и в теории не могут принести каких-то сложностей — что было «а вот пустое место — пустая горизонтальная строка, значит начало функции», что станет «пустое место — дополнительный отступ, значит начало функции» — все это простейшие нейронные цепочки, одинаково комфортные после переобучения.
Я имеею образования в области нейрофизиологии, соответственно эта дискуссия — без меня.
Кто-нибудь еще кроме автора переучивался писать открывающую скобу на той же строке?
Как результат?
Не раз, причем в обе стороны (с «на следующей» на «на той же» и обратно). Никаких проблем. Проблема надуманная.
На чем бы остановили свой выбор?
На Java — на той же. На C# — на следующей.
А в C# вы стали ставить скобку на следующей строке потому что тоже не смогли настроить студию, или по какой-либо другой причине?
Потому, что так написано в style guide тех проектов, в которых я писал код на C#. А поскольку лично для себя я на C# не пишу, то и потребности пересматривать это у меня нет.
я всегда так писал, пишу и буду писать… за 17 лет в программировании я посчитал это самым идеальным решением, и вполне читаемым и удобным. имхо.
Переучиваться? Современные IDE позволяют настроить coding style и сами будут все подчищать следуя заданным настройкам.
Современные IDE прячут эту настройку настолько глубоко, что быстро и безболезненно переучивают программиста на тот стиль, который был задан разработчиком :)
Если уж так прямо волнует отсутствие единообразия синтаксиса, могу предложить сравнить с языком Python, который, кстати, имеет отличную библиотеку обвязки С++ boost::python
Python:
if a < b: # без вариантов
    a = c
    func( b * b )
else: # без вариантов
    b = c
    func( a * a )

C++:
if( a < b ) { // или всё же на следующей строке?
    a = c;
    func( b * b );
} // или всё же на той же строке, что и else! а может вообще на предыдущей!
else { // или всё же на следующей строке?
    b = c;
    func( a * a );
} // или всё же на следующей строке?
По поводу «а не оставлять ли } на строке с последним оператором» — будет слишком неудобно добавлять новые инструкции в блок кода. В остальном, по возможности — как в Python, ибо короче и визуально совпадает.
UFO just landed and posted this here
Формально — при заявленных им условиях, которые Вы почему-то не отквотили — автор прав. Но практического значения, разумеется, не имеет. Тем более, что там по соседству есть действительно ложное утверждение…
UFO just landed and posted this here
На самом деле просто нужно иногда менять привычные вещи. Задействовать левое полушарие по полной. Пересесть на мак с писи, перепрошить коммуникатор, поменять стиль кода — это всё одного поля ягоды. Уверен, что через 3 года вы так же ръяно будете отстаивать египетские скобки.
Интереснее будет за 3 года перейти на язык, где фигурные скобки не используются для выделения блоков кода. :)
Если это будет язык типа python, тогда после описанного стиля на него будет перейти довольно легко (в плане визуального распознавания блоков команд).
Египетские скобки — так с перехода на них и начинается статья, я их и сейчас отстаиваю — код короче, похож на python, применяются в java и qt…
Все эти достоинства будет малоприменимы для программиста, пишущего не C# и не использующего python, не правда ли? Ну кроме спорного «код короче».
Некоторые описанные приемы можно применять и на других языках — например, более короткие комментарии начала файла, и т. п.
более короткие комментарии начала файла, и т. п.

А они в цивилизованных проектах «на других языках» (я сейчас про C#) вообще не нужны, на мой взгляд. Это банальный мусор.
This file is licensed under GPL, www.gnu.org/copyleft/gpl.html

Вероятно, я отстал от современных трендов программирования на C#. А как сейчас принято указывать тип лицензии, по которой распространяется код?
Во-первых, для ощутимой части кода это вообще не надо. Просто потому, что он не распространяется ни по какой лицензии.

Во-вторых, для остальной части кода берется license.txt, кладется в корень, и все. А в некоторых случаях и его не надо (это я на исходники asp.net mvc rtm) смотрю.

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

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

Еще пример: открывающая скобка на новой строке повысит читаемость кода, если в данном проекте приняты большие выражения в условном операторе (в коде бизнес-правил легко может быть 7-10 строк в выражении внутри if())

Так что да, эти приемы могут быть применены. Равно как и обратные к ним.
Для многострочных условий if я тоже делаю скобку на новой строке — потому что иначе будет сложно увидеть конец условия и начало тела. Аналогично после списков инициализации.
Автоматическое рисование линий после начала функции не особо нужно — после переобучения достаточно ориентироватся по отступам.
Тогда, Вы сделали себе тоже самое, от чего избавляетесь:
Если у меня длинное условие, скобка блока, на новой строке, если короткое, то сразу после условия. — вместо — скобка блока всегда на новой строке.

В статье вы выводите правила, якобы стройные и понятные Вам, но с учетом Ваших некоторых комментариев эти правила имеют исключения. И эти исключения противоречат Вашим же правилам упрощения.
Так это вынужденное отступление от правил, иначе код будет менее читабельным. Зачем слепо следовать правилам во всех случаях?
Да, прошу прощения, запутался после прочтения комментариев :) Имелось в виду — будете отстаивать скобки с новой строки
У вас как-то в статье слишком много пустых строк и отступов между абзацами. Меньше статьи на экран влезает, скроллить чаще нужно.
Не будьте так строги к автору: статья читается все-таки последовательно, рука с колесика мыши практически не убирается.

Сложные места в программе читаются в произвольном порядке (прочитав незнакомую переменную, читатель зачастую вынужден искать ее объявление, а потом возвращаться обратно), да еще и параллельно с написанием своего кода.

А так да, очень интересное замечание…
Сложные места в программе читаются в произвольном порядке (прочитав незнакомую переменную, читатель зачастую вынужден искать ее объявление, а потом возвращаться обратно)

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

Спасибо, но у меня нет столько денег.
Нет, я предлагаю не оценивать продуктивность или контрпродуктивность стиля кодирования по блокноту.
«Продуктивность» — неверное слово.
Я оцениваю читаемость.
… и читаемость тоже нельзя оценивать по блокноту.
Да, по блокноту — нельзя.

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

(да, это не для переменных, это для классов, методов, свойств, функций и так далее)
Я не говорил, что использую только скролл, я говорил что использую скролл.
Сформулирую несколько по-другому: меня бесит, если для этого приходится использовать скроллинг.

Поэтому все сложные места я стараюсь уместить в экран.
Ну так не используйте скроллинг. Я вот не использую, вне зависимости от объемов кода.
И каким образом мне его не использовать, если сложный алгоритм на три экрана растянут?
Лично я для этих целей, в зависимости от того, где сейчас рука, либо навожу курсор мыши на переменную, либо перехожу стрелками и нажимаю Ctrl-F1.
А более емкие и узконаправленные методы писать не пробовали?
Размазывание сложного кода по разным методам — тоже не всегда выход.
Ну если идет хардкорная алгоритмика, то конечно, для бизнес-логики даже 50 функциональных строк — перебор.
прочитав незнакомую переменную, читатель зачастую вынужден искать ее объявление, а потом возвращаться обратно

Хотя на самом деле, это вообще говорит о том, что код написан, скажем так, посредственно. Как завещал нам Липперт, определение переменной не имеет особого значения при чтении кода, ее название имеет. Старый спор за и против var в C#.
Ну а кроме переменных, что, проблем при чтении кода не бывает?

Как насчет оператора if — else, растянутого на несколько экранов?
Двух крупных циклов подряд?

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

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

Да, это все говорит о посредственности кода, но ведь про то и речь.

Речь о том, что такой код надо переписывать, никакой coding style его не спасет.
У текста другой style guide, потому что язык другой.
Язык-то другой, но обоснование на первый взгляд все равно подходит. В том и смысл шутки.
Тогда потеряется блочная структура. Поэтому обоснование не подходит.
Да сколько можно шутку обсуждать?!
у некоторых людей логическое мышление преобладает над образным.
В целом правила интересные, но хотелось бы добавить несколько мыслей.

Includes
Если некоторый файл довольно насыщен функционалом, то у него может быть до 15 инклюдов. В таком случае имеет смысл визуально разбить инклюды на группы — свои заголовочные файлы, сторонние и системные.

Однозначно, такой файл, как всемирно известный stdafx.h, тоже желательно «разбавить» переводами строк, поскольку инклюды — это и есть его основное содержание.

forward declarations в моей практике очень редко требовались для компиляции всего файла, гораздо чаще они требовались исключительно для одного конкретного блока кода:
class some_class;
class some_other_class {
public:
  typedef some_class some_identifier;
}


В таком случае я предпочитаю писать подобные связанные объявления рядом, а не «утаскивать» в начало файла.

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

Имена. Те, кто считает, что some_name и someName отличаются на одно нажатие ужасной комбинации «Shift+_», ошибаются: заглавные буквы тоже требуют нажатия шифта, так что отличаются эти два стиля только одним нажатием дефиса. Да, на некоторых клавиатурах дефис задвинут в какое-то ужасное место, но я почему-то считаю, что это проблема исключительно владельцев плохих клавиатур.

Между тем, в C++ существуют сущности, одинаковые с точки зрения языка, но зачастую совершенно разные семантически: классы и умные структуры. Классы — это понятие ООП, для них характерны наследование и полиморфизм, хотя они и могут быть созданы на стеке или включены в другой класс как поле, это считается плохим стилем, и потому объекты, как правило, передаются только по указателю. Существует даже такая разновидность классов, как абстрактные, и их-то по значению вообще никогда не передают.

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

Мое предложение — использование различных стилей наименования для отделения классов от структур:
классы — IDataQuery, DataStore, PersonCollection;
объекты — dataQuery, dataStore, personCollection;
структуры (как типы, так и переменные) — shared_ptr, scope_lock, native_holder.
Табы или пробелы?

Табами довольно сложно выровнять код по нужному символу, что делает затруднительным «красивое» выравнивание вроде такого:
int v = some_long_expression
      + some_other_expression
      + some_last_expression;


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

Дополнительные сложности появляются в C# с его Linq, точнее с правилом оформления «выравниваем по первому символу первого слова from». Альтернативные же способы выравнивания приведут к очень некрасивому результату. Выход один — всегда переносить from на новую строку (или писать весь запрос в одну строчку).
после «int v» ставится табуляция, и символы = + идут на одном и том же уровне.
Да вы что?!
Прямо-таки независимо от размера табуляции? А если он два символа? 4?
И независимо от типа и имени переменной? А если там не int v, а std::string result_message?
ko.com.ua/dazhe_ne_lezhalo_valyalos_pod_nogami_38851
>поразительно — только в 2008 году кто-то до этого додумался и предложил символы табуляции, обозначающие не «длинные пробелы», а виртуальные колонки переменной ширины.

Соответственно, хоть result_message, хоть v — без разницы.
И много IDE подобное поддерживает?
А ведь для того, чтобы текст программы не «поехал» у стороннего читателя, требуется, чтобы все IDE (а также несколько популярных просмоторщиков текстовых файлов) поддерживали подобную возможность.

Так что до подобного использования табуляции дойдет еще не скоро…
>stdafx.h

Кстати, если проект кроссплатформенный, то лучше называть файл pch.h вместо stdafx.h — потому что afx указывает на MFC, а так явно говорится, что precompiled header.

>отличаются эти два стиля только одним нажатием дефиса

о том и речь.

>различных стилей наименования для отделения классов от структур

С течением времени многие структуры усложняются и перерастают в классы. Если класс с маленькой буквы, то нельзя именовать переменную «Name name;», как это часто делают в java, и приходится выдумывать имена, и поиск по имени типа работает хуже.
Умная структура — это сущность, которая сама по себе значительно сложнее большинства классов, и классом с точки зрения ООП она никогда не станет принципиально.

При каких условиях shared_ptr станет классом (и память под него будет выделяться оператором new)? Никогда, поскольку он сам для того и создан, чтобы управлять выделением памяти.

Когда scope_lock станет классом? Никогда, поскольку единственная цель этой структуры — наблюдение за областью видимости переменной, и она всегда создается на стеке.

Что насчет native_holder (костыль, придуманный мною для размещения нативных структур в полях объекта из управляемой кучи):
template <typename T>
[StructLayout(System::Runtime::InteropServices::LayoutKind::Explicit, Size=sizeof(T))]
value struct native_holder
{
	operator interior_ptr<T>()
	{
		return (interior_ptr<T>)this;
	}

	void init() { pin_ptr<T> ptr = *this; new (ptr) T(); }
	template <typename T1> void init(T1 value) { pin_ptr<T> ptr = *this; new (ptr) T(value); }
	void release() { pin_ptr<T> ptr = *this; ptr->T::~T(); }
};

Впрочем, это уже не чистый C++…
Комментарии начала файла не нужно делать короче — их нужно просто выкинуть.
Попробуйте взглянуть на стилистические конвенции не с точки зрения экономии вертикального места (почти все ЖК-мониторы прекрасно поворачиваются на 90% и организовать ide/консоль в несколько колонок тоже не сложно), а с точки зрения уменьшение вероятности возникновения ошибки при его изменении или написании.

По скобкам (и прочим конвенциям для C-подобного синтаксиса) стоит почитать МакКоннела, честно говоря мне сложно представить кто и что может сказать по этому вопросу после него.

Для меня сейчас куда более загадочным в плане удобных конвенций является JS, лисповые плохо подходят, большинство сишных тоже не фонтан.
Sign up to leave a comment.

Articles