2,1
рейтинг
24 января 2012 в 00:01

Разработка → Открытое письмо лидерам JS касательно точек с запятой перевод

Такое письмо я получил от Шона Сильвы прошлой ночью:
Я просматривал ваш код для проекта npm.js (в частности, вот этот файл: https://github.com/isaacs/npm/blob/master/lib/npm.js), и заметил, что вы выравниваете запятые под ‘r’ в выражениях var, и под [ и { в литералах массивов/объектов. Мне очень нравится такой способ форматирования, но я не решаюсь его использовать, так как большинство ресурсов о js насаждают страх перед хаосом, который воцарится в коде из-за автоматической расстановки точек с запятой, если вы не будете заканчивать строки чем-нибудь, что предполагает продолжение.
Безопасно ли располагать запятые таким образом в «браузерном» коде, или это только в node возможно?

Я написал несколько абзацев, и решил сократить их до следующего ответа:
Да, это полностью безопасно, и это совершенно валидный JS, понимаемый каждым браузером. Closure compiler, yuicompressor, packer, и jsmin — все могут правильно минифицировать его. Производительность нигде не просядет.
Мне жаль, что вместо того, чтобы обучать вас, лидеры сообщества этого языка прививали вам ложь и страхи. Это позор. Я рекомендую изучить, как на самом деле терминируются инструкции в JS (и в каких случаях они нетерминируемы) — и вы сможете писать код, который сочтете прекрасным.


Inimino запостил очень четкое объяснение. В его стиле — четкое, ясное, авторитетное, с хорошим исследованием, — и он, как всегда, оставил свое мнение при себе.
Я собираюсь быть немножко более пристрастным.

Правила

В общем и целом, \n всегда заканчивает выражения, за исключением следующих случаев:
  • Выражение несет незакрытую круглую скобку, литерал массива, литерал объекта или заканчивается любым другим способом, который не является легальным способом закрыть выражение (например, кончается на . или ,);
  • Строка представляет из себя --, ++ (в том случае, если следующий токен будет декрементирован/инкрементирован);
  • Это for(), while(), do, if(), или else, и на строке нет {
  • Следующая строка начинается с [, (, +, *, /, -, ,, ., или любого бинарного оператора, который может находиться в одном выражении только между двумя токенами.

Первое правило довольно очевидно. Даже JSLint не возражает против символов \n в JSON, в конструкциях со скобками, и в var-выражениях, которые простираются на несколько строк, кончающихся на ,.
Второе — очень странное. Я никогда не встречал таких вещей (за исключением такого рода бесед), чтобы кто-то хотел написать i\n++\nj, но, по факту, это парсится как i; ++j, а не как i++; j
Третье хорошо понимают, хотя обычно пренебрегают им: if (x)\ny() эквивалентно if (x) { y() }. Эта конструкция не заканчивается, пока не будет встречен блок или выражение. ; является валидным выражением JavaScript, так что if(x); эквивалентно if(x){} или «если x, ничего не делать.» Это обычно применяется к циклам, в которых проверка является также обновлением счетчика. Необычно, но встречается.
Четвертое, обычно, внушающий FUD, «ох неты, тебе нужны точки с запятой!»-случай. Но, оказывается, довольно просто предварить такие строки точками с запятыми, если вы не хотели сделать их продолжениями предыдущих.
Например, вместо:
foo();
[1,2,3].forEach(bar);
можно написать:
foo()
;[1,2,3].forEach(bar)

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

Ограниченное правило

Еще один стандартный аргумент в пользу точек с запятой имеет отношение к AIS и ограниченным правилам. К примеру, если у вас стоит \n сразу после токена return, throw, break, continue, или ++ или -- в постфиксной форме (например, x++\n или y--\n), то сие закончит выражение — без исключения.
//ок
return 7

//вероятно, ошибка
return
       7
И еще раз: несмотря на это, заметить и предовратить такие вещи проще, как только вы отвыкнете завершать каждое выражение точкой с запятой. Когда я встречаю второе правило, мой мозг инстинктивно ассоциирует \n c «ок, с этим всё», потому что для терминации return всегда достаточно только перевода строки.
Выравнивание важнейших токенов в левой части экрана делает их явно более легкими для быстрого анализа человеком. Кипы исследований быстрого чтения и движений глаз утверждают, что отсутствующий токен справа проглядят с большей вероятностью, чем отсутствующий токен слева. Так что — я повторюсь — перемещайте менее важные вещи направо, а слева ставьте более важные вещи.

Так какой стиль лучше?

В той мере, в какой вообще существует объективно «лучший стиль», мне кажется, что стиль «минимум точек с запятыми/запятые первыми» — слегка лучше; по двум причинам: потому что этот стиль лучше читается и потому что он поощряет разработчиков лучше понимать язык, который они используют.
Я могу гарантировать, что, как бы мало вас это не волновало, меня ваш JS-код волнует меньше, чем мой — вас. Это не та статья, где я пытаюсь убедить вас писать код в моем стиле. Каждый сам должен решить, какова политика ношения штанов в его доме.
Как проявление доброй воли…

Хорошие причины ставить точки с запятой

Причины для избыточного использования точек с запятой — эстетика и политика.
«Я ставлю точки с запятой в JS, потому что иначе это не будет валидным C/C++/Java/Ещечёмто». Если вы вынуждены писать много Java- или C-кода в проекте, и хотите, чтобы ваш JS не слишком выделялся — то это достойный довод. (Проект Cassis доводит этот довод до абсурдного завершения).
«Мы так делаем, потому что используем линтер, и линтер велит так». Консистентность — важна, и линтеры — один из способов достижения консистентности кода для группы. Задача написания линтера, совместимого с npm, стоит в моем todo-листе, но не очень высоко.

Cамые ужасные причины везде ставить точки с запятой

«Они обязательны, потому что ASI — ненадежно» О, да ладно??
Эти правила восходят к заре JS, к поздним 90-м. Они не новы, и мое мнение — нет прощения никому, называющему себя профессионалом в JS и не понимающему правила прерывания выражений. Это откровенно безответственно со стороны лидеров сообщества JS — продолжать распространять неясность вместо понимания.
Более того, типичное место, где AIS нападает исподтишка — ограниченные правила. Добавление точек с запятой в каждой строчке не заставит return\nfoo возвращать что-то, кроме undefined. Проблема в том, что вы используете перевод строки, а не в том, что вы не ставите точки с запятой.
Единственный способ навсегда предотвратить ошибки с ограниченными правилами — всегда использовать точки с запятой и никогда не ставить переносы строки. Никто этого не предлагает. Так что перестаньте говорить об этом так, будто это имеет значение, или предлагать избыточные точки с запятой как альтернативу пониманию ASI. Вы обязаны понимать ASI, чтобы быть компетентным JS-программистом, точка.
И это приводит нас к тому, что…

Я становлюсь весь из себя необъективный и взбешиваю вас (несмотря на благородную попытку сделать противоположное)

Если вы не понимаете, как терминируются выражения в JS, то вы просто-напросто не знаете JS как следует, и не должны профессионально писать на JS без надзора, и определенно не должны давать советы о том, как на нем писать.
Думаю, я только что оскорбил вас. Очень жаль. Я знаю, что вы знаете множество вещей, касающихся JS — таких, как DOM, и CSS, и баги MSIE, и jQuery. Вы, вероятно, потратили некоторое время, изучая замыкания, и прототипы, и области видимости, и объекты активации, и даже написали несколько расширений для V8 или SpiderMonkey. Вы не глупы, я уверен. На самом деле, вы, скорее всего, умнее меня, и, наверное, более милы и лучше выглядите. Я уверен: у нас много общего, и мы могли бы быть друзьями.
Но если вы не понимаете, что из себя представляет выражение в JS, то в вашем понимании того, что, возможно, является самым фундаментальным аспектом языка — огромная дыра.
И это нормально. Я не очень хорошо говорю на испанском и мой C, в общем, на уровне новичка; и я не называю себя экспертом в этих вещах, — хотя и знаю достаточно, чтобы выкрутиться в большинстве ситуаций. Если бы я собирался на работу, которая подразумевает много разговоров на испанском или много C — я бы хотел, чтобы за мной присматривал кто-нибудь, дабы помочь избежать каких-то серьезных ошибок.
Как и большинство вещей в JS, правила терминирования выражений не очень хорошо спроектированы, но они и не очень трудны для понимания и использования. Это понимание просто требует немножко времени и усилий.
Устройтесь поудобнее с горячим шоколадом и спецификацией ECMAScript как-нибудь субботним вечером. Попрактикуйтесь. Поиграйте с тестовыми программами. Это хорошее времяпрепровождение.
Или не делайте этого, если не хотите. Это ваша жизнь. Наверняка у вас есть занятия получше.
Только перестаньте делать авторитетные заявления типа «заканчивайте все строки точками с запятой, чтобы быть в безопасности». Это ничуть не безопаснее и не надежнее.

Дополнение 1: «Лидеры»

Так, мистер-гладящий-против-шерсти, кто же эти «лидеры», о которых вы говорите? Почему вы не называете имен?

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

Дополнение 2: Адепты Грамотного Программирования

(прим. переводчика: имеется ввиду literary programming)
Но в английском языке мы ставим знаки препинания в конце, а не в начале.

JavaScript — это не английский. Мы так же не обозначаем владение (или отношение объект-глагол) с помощью точки в английском. В английском нет литералов объектов, и мы делаем отступ только в первой строке абзаца, а не во всех предложениях.
Это такой глупый довод, что у меня нет выбора, кроме того, чтобы влюбиться в в него.
Я начал вас оскорблять, но вы завоевали мое сердце, Адепт Грамотного Программирования. С этого момента я буду ставить переводы строки только в конце функций, не в середине, и делать отступ на первой строке каждой из них.

Дополнение 3: Педантизм

Чо ты лезешь в мой код? Ты чо педант штоле?

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

(от переводчика: как переводчик, хочу выразить благодарность за помощь с переводом и корректорскую работу своей любимой женщине — филологу)
Перевод: Isaac Z. Schlueter
Константин Китманов @k12th
карма
85,5
рейтинг 2,1
JS
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (109)

  • +2
    Мило. Слов многовато, суть слегка теряется (хотя может дело в том, что я просто дико устал и уже нифига не соображаю), но написано очень мило. Не знаю, настолько ли хорош стиль оригинала, но перевод получился отличный.
    • +1
      Спасибо. Насчет стиля — я старался передать стиль оригинала, насколько смог.
  • +1
    Перевод хорошо передал эмоции :)
    • 0
      Это потому что их в оригинале много:)
  • НЛО прилетело и опубликовало эту надпись здесь
    • НЛО прилетело и опубликовало эту надпись здесь
      • –2
        программист не программист если не включает мозг.
        • НЛО прилетело и опубликовало эту надпись здесь
          • +14
            Вы специально пишете с грамматическими ошибками, или русский не ваш родной язык?
          • НЛО прилетело и опубликовало эту надпись здесь
            • НЛО прилетело и опубликовало эту надпись здесь
        • +1
          Пишете на брейфаке, только там нужно включать мозг по-полной.
      • 0
        Это неплохой аргумент, на самом деле.
      • +5
        В русском языке «рас» — это родительный падеж множественного числа слóва «раса».
        • НЛО прилетело и опубликовало эту надпись здесь
  • +3
    К правилам, наверное, можно еще отнести, что "\" игнорит конец строки в литералах. В результате получаем:
    var text = 'Multiline \
    long string \
    declaration\
    !';
    • +2
      Обратный слэш экранирует специальные символы. Вспомните:
      var text = 'it\'s single quote mark!'

      То же самое и тут, только в качестве спецсимвола выступает перевод строки.

      Вообще не очень люблю эту штуку, неряшливо выглядит. Жаль, что в JS нет более удачных способов записи многострочных литералов.
      • –1
        Ну еще можно писать 'Multiline \nlong string \ndeclaration\n!';
        Хотя да, выглядит еще хуже :D
      • 0
        Ну да, в Вашем примере «\'» приводит к экранированию, и апостроф воспринимается как апостроф.

        Но с переводом строки ситуация ведь совершенно противоположная: там «\» приводит к игнорированию, и перевод строки не воспринимается как перевод строки (и вообще никак не воспринимается: он игнорируется).
        • 0
          Эмм, не совсем. Без \ символ ' (это, кстати, не апостроф, а т.н. одинарная кавычка, апостроф — `) будет воспринят как завершение строкового литерала.

          Без \ символ новой строки будет воспринят, как завершение выражения. Так как литерал не закрыт, это будет ошибкой. Ну, а с ним новая строка будет экранирована и попадет в содержимое литерала.
          Перевод строки не игнорируется в этом случае. Попробуйте:
          alert('Hello, world!')
          alert('Hello,\nworld!')
          • 0
            Вы говорите о спец. символах, а в данном случае имеется фактический перевод на новую строку: CR LF. Попробуйте:
            alert('Hello, world!');
            alert('Hello, \
            world!');
            alert('Hello, \nworld!);

            Первые два алерта будут одинаковыми. Потому-что во втором алерте "\" ничего не экранирует, а просто игнорирует, поэтому в литерал новая строка не попадает.
  • +1
    … хотя, наверное нет. Это все же не из стандарта. К правилам не относится. Скорее просто к трюкам. Пользуюсь давно, нареканий не замечал.
  • –7
    А в Python вообще нет ";" например.
    • +4
      Все-таки Python это другая идеология.
      • –1
        Объясните пожалуйста, при чем тут идеология. Прости мне моё невежество. Спасибо.
        • 0
          Определись уже на ты или на вы) А вообще почитай историю создания JavaScript.
          • –1
            Я да.
          • –2
            Выше вы докопались грамматических ошибок, теперь обращаются к вам не так. Мастер флуда?
            • 0
              Нет. Меня устроило бы любое обращение, я не гордый.
    • +2
      Вообще он там есть, точно так же может завершать строки. Только от его наличия ничего не зависит, потому что нет правил, не завершающих строку, которые основываются на содержимом следующей строки (как здесь). Решение о незавершенности принимается только исходя из текущей строки.
  • +17
    Я, к примеру, знаю правила постановки точки с запятой, но все равно ставлю их везде. Так js является не первым языком программирования, с которым я познакомился. И мне не всегда комфортно читать код без точек с запятой. И мне кажется, что большинство программистов, советует использовать точки с запятой, не из-за не понимания конструкций языка, а из-за влияния других языков на их стиль программирования, но это лично мое мнение. И когда новички обращаются с вопросом о точках с запятыми они просто, советуют ставить их всегда, что бы не объяснять все правила. А человек который действительно хочет разобраться в тонкостях языка найдет их в спецификации.
    • +2
      Авто просит, чтобы когда кому-то лень объяснять правила новичкам, этот кто-то честно сказал: «Мне лень — ставь везде и не ошибешься. А если хочешь разобраться — то вот статья, где все расписано».

      Лично мне, честно говоря, комфортнее без точек с запятой — для меня это визуальный мусор. Но я могу и так и так писать.
  • 0
    Интересно какая история изучения языков программирования у автора. Небольшое погружение в собственную — Pascal, C, C++, C#, позволяет c уверенностью сказать, что добровольное покушение на точку с запятой, очень чуждое и как минимум неприятное занятие.
    • +2
      Автор отмечает это в разделе «Хорошие причины ставить точку с запятой».
      Автор вообще не просит совсем не ставить точку с запятой. Автор просит разобраться с этим вопросом и не врать другим.
    • 0
      К хорошему привыкаешь быстро. У меня в истории почти ваш список (без до-диеза), плюс ещё пару раз по столько языков и все с точками с запятыми. А потом я заинтересовался Руби и добровольно повыкидывал точки с запятой из яваскриптов :)
  • +14
    Все стандарты кодирования вырабатываются для избежания глупых ошибок, а также для облегчения чтения кода, который будет написан в одном стиле.

    Код npm.js ужасен. И совершенно не важно как автор оригинальной статьи знает стандарт, если его код тяжело читать.

    ЗЫ: Запятая в начале удобна только в одном случае: кода интерпритатор неправильно воспринимает запятую и сразу следом закрывающую квадратную или фигурную скобку. Привет IE. Но это никак не отменяет нормальной расстановки отступов без всяких выравниваний под "[" и "{", которые логику отступов рушат.
    • +3
      Код действительно трудно читать, хотя я читаю javascript-код уже 6 лет.

      На лицо влияние Ruby и Coffeescript на автора (у него на GitHub есть такие проекты).
  • +16
    ИМХО, код npm.js легко читается только его автором. Подобная расстановка запятых для мне не только усложняет чтение но и усложняет набор таких исходников и, думаю, IDE c этим плохо дружат.
  • 0
    Сколько сил вбухано в споры о ';'
    • +3
      Действительно, мне вот больше интересно, чем он руководствуется в расстановке {}, как пример:

      if (typeof args[args.length — 1] !== «function») {
      args.push(defaultCb)
      }
      if (args.length === 1) args.unshift([])

      Вообще всегда поражало стремление новаторов извратить бест практики отработанные годами:
      , «list»: «ls»
      , «la»: «ls»
      • –2
        , «list»: «ls»
        , «la»: «ls»

        Мде, как говорит Бочарик: «Это бесит».
        Хотя в «новаторском» коде есть и приятные моменты, например, всегда расставлять пробелы после открывающей и перед закрывающей скобками:
        valera( 2, 5 );
        [ 1, 2, 3, 4 ];
        (в данном случае я ссылаюсь на Резига)
        Раньше считал такой подход избыточным, сейчас он помогает делать код более читабельным.

        Кстати, немножко оффтоп: почему так завелось, что в JS открывающая скобка остается на той же линии, а в других языках (например, в php) переносится:
        //JS
        if( true ) {
          doSomething();
        }
        
        //php 
        if(true)
        {
         do_something();
        }
        • +5
          Египетская нотация. И в php такая используется в том числе. Просто в разных проектах по-разному
          • НЛО прилетело и опубликовало эту надпись здесь
        • 0
          Кому как удобнее, тот так и пишет…
          • 0
            Есть негласные стандарты. Например, в JS все используют camelCase и «египетскую нотацию».
        • 0
          Сейчас в PHP, вроде, тоже второй вариант чаще используется.
        • +2
          мне кажется, зависит от ваших предпочтений. в одной из компаний, где я работал, в c++ и c# тоже принято использовать египетские скобки.
        • 0
          Меня всегда удивляли минусы на хабре. Хоть бы аргументировали.
        • –2
          За пробелы после/перед круглыми скобкам с удовольствием ломал бы кодерам пальцы, не будь это запрещено УК РФ.
          Надо бы пересмотреть УК, староват он...
          • +1
            Спокойнее к этому надо относится, спокойнее:)
          • +2
            Очень некрасиво писать такие вещи незнакомому человеку.
            • –1
              В интернете опяять кто-то неправ? ))
              Извините, если мой комментарий показался вам через чур желчным, я не пытался конкретно вас задеть.
  • +1
    Ввели бы в strict mode обязательную расстановку точек с запятой, мир бы стал добрее. Ну, или, в крайнем, придумали бы какой-нибудь super srtict mode, где эти правила будут основной фишкой.
    • 0
      И типизированные переменные и (особенно) параметры функций туда же, как и явное задание необязательности аргумента и использование неопределенного количества аргументов. Лично у меня время отладки сократилось бы раза в два.
      • 0
        Это уже будет «другой» Javascript.
        • 0
          Внутри блока «strict» он и так «другой».
          • 0
            Это тот же Яваскрипт, но немножко обрезанный. В вашем случае в язык добавляются новые синтаксические конструкции.
  • +1
    Пишу сейчас парсинг js, просто материться хочется с этой необязательной ";" в конце.
    Мало того, что приходится писать немало кода на обработку лексемы перевода строки, которую в 99% случаев можно тупо пропустить, так еще и получаем сложности с исключениями (return/break/throw/continue/...).
    • 0
      Есть еще одна проблема (когда был студентом — так и не смог ее решить на ANTLR) с инлайн-синтаксисом для регекспов и распознаванием отдельной лексемы '/':
      var x = /^banana[^s]+$/;

      Хотя после написания парсера php эти проблемы уже кажутся мелочью…
      • –1
        Угу, просто используется 2 разных начальных символа для лексера — InputElementDiv / InputElementRegexp.
        Различие только в трактовке лексем начинающихся на слэш — "/" и "/=".
        Собственно как побороть в ANTLR — хз. Сам я поступил довольно просто — сделал переключатель режима работы лексера — regexp/обычный, и прогонял парсер 2 раза на родительском для regexp'a выражении.
        Да, оверхед, но иначе никак.
        Правда пишу я, используя свои тулзы. Увы готовые совсем не подходят, ибо мне нужно «parser tree», а не AST, который и то не все генерить умеют. Да и lookahead в грамматике рулит, хз как его запилить в том же bison'e.
        • 0
          Не, можно сделать в однопроходном режиме. Но только если заставить лексер знать состояние парсера, чтобы правильно интерпретировать вход '/' — как начало регекспа или просто как знак деления. С точки зрения классических LL(k) это хак.
          А что вы понимаете под parser tree, если не секрет?
          • +1
            > С точки зрения классических LL(k) это хак.
            Я адепт LR, и SLR/LALR в частности :)
            Хотя несмотря на это, думал над ANTLR'ом, да.
            > Не, можно сделать в однопроходном режиме.
            Да, так и сделано у меня, немного перепутал, почему-то когда писал коммент подумалось что возможна двоякость, но проверил — нет, всё ок, только RegExpLiteral начинается с "/" в PrimaryExpression, так что никаких Reduce-Reduce конфликтов нету, и это чисто проблема лексера.
            > Но только если заставить лексер знать состояние парсера
            Ну да, я об этом и писал, только у меня отношения Parser > Lexer, то есть парсер устанавливает состояние лексера (regexp/normal), а не лексер получает доступ к внутренностям парсера. Я считаю что это более верный подход.
            > А что вы понимаете под parser tree, если не секрет?
            Ну собственно синтаксическое дерево разбора.
            Для грамматики:
            expr ::= term (( PLUS | MINUS) term)*
            term ::= factor (( MULT | DIV) factor)*
            factor ::= NUMBER

            И примера 1+2*3 дерево такое:
            expr
            term
            factor
            NUMBER [1]
            PLUS
            factor
            NUMBER [2]
            MULT
            term
            factor
            NUMBER [3]

            Не знаю как в русскоязычной терминологии будет, но в англоязычной так и называется parse tree.
            AST более высокоуровневая конструкция, которая строится по нашим правилам, а не по грамматике.
            Для примера выше вполне может быть таким:
            *
            +
            1
            2
            3
            • 0
              ок, надо было жать предпросмотр :)
              Ну в общем пробелы убрались и появились лишние переводы строки, но идея я думаю понятна.
              • 0
                Да, спасибо
    • 0
      Если не секрет, зачем такая работа?
      • 0
        Пишу утилиту для помощи в деобфускации сжатого js-кода. Там 2 этапа:
        1. «Причёсываем» код, расставляя пробелы и переносы строки там где нужно.
        2. Умное переименование переменных/функций/членов. Тупой Ctrl+R не пройдет по многим причинам. Основных две — scope и все танцы вокруг него (так называемое «всплытие» / постройка [[Scope]] на этапе создания функции/ ...), члены — нужно знать что это за объект и его прототип. Поэтому нужна частичная интерпретация js-кода, и учёт всех теневых влияний стандарта.

        Собственно для обоих частей и нужно построение синтаксического дерева.
        Причём желательно избежать 2х проходов (нам же нужно знать позиции в тексте, для переименования), поэтому нужно дерево построенное по собственным принципам — location(child[i]) < location(child[i + k]), грубо говоря. Дабы при выполнении первого этапа можно было изменять дерево на лету.
        • 0
          Понятно. Интересная задача.
  • +1
    js самый магический язык из наиболее популярных сейчас.
    • 0
      Где там магия?
      • –1
        как мне кажется — в традиционной (в какой-то момент времени) для всех браузеров «мягкости» к ошибкам. Мол, ну забыл пользователь (закрыть элемент, добавить атрибут, поставить точку с запятой), не огорчать же его. Для начинающих может и неплоха такая магия, а вот потом — это ж сущий кошмар.
      • +2
        Вот здесь, например. Совсем недавно на хабре проскакивало.
        • НЛО прилетело и опубликовало эту надпись здесь
          • +4
            Документированность магии не меняет ее сути ;)
            Интересная получилась опечатка: спорите с магией, говоря о святости.
    • 0
      перл?)
  • +8
    Статья интересная, но такая расстановка запятых меня (лично меня, no offense) люто бесит. И такой код плохо читается.
  • 0
    Думаю, это дело привычки, на самом деле.
  • +1
    ИМХО.

    Поддерживаю автора. Спасибо переводчику.

    Главное чтоб стандарт языка позволял. Остальное это уже на усмотрение руководителя проекта. Пусть хоть каждый символ на отдельной строке будет. Если ЯП позволяет, а тем кто этот код пишет/поддерживает так удобно, то это их полное право.
  • 0
    "JavaScript — это не английский."

    Код — это текст. И что бы не говорили — базовые правила типографии к коду так же применимы. Если говорить в контексте темы статьи — отсутствие символа ";" или запятой в конце строки подсознательно говорит нам о «незавершенности предложения» и что дальше будет продолжение. А тут бац — конец, затем сразу же начало другого.

    Код, в основном, состоит из однострочных «предложений» зачем их разбивать — не понятно. Зачем лишний раз заставлять напрягает глаза — пойди-ка посмотри, что там на следующей строке?
    И знание «правил терминирования выражений» здесь вообще не при чем — дело в восприятии.

    Так же хочется вспомнить отсутствие пробела перед запятой и его наличие после. Я понимаю, что не роман читаю, но символы-то те же и мы привыкли так их читать ещё со школы. Не понимаю, почему некоторые делают иначе.
    • 0
      Кажется, вы не дали себе труда внимательно прочесть до конца.
      • 0
        Вам только кажется.
        Я прекрасно понимаю что хотел сказать автор. Я только привел причину, по которой всё-таки лучше ставить точку с запятой и рассказывать об этом новичкам.
        • 0
          Там есть специальный раздел про literary programming. Просто перечитайте его еще раз, хорошо?
          • 0
            Именно из-за этого раздела я написал первый пост.
            Автор доходит до крайностей. Из приведённой им же цитаты видно, что речь идет только о знаках препинания. Причем тут отступы? И я говорил, что только некоторые правила применимы, касающиеся этих самых знаков.

            С момента, как он начнет делать переводы строк только в конце функций, ему так же придется отказаться от camelCase. В обычных текстах всё совсем наоборот — только первая буква может быть заглавной (аббревиатуры не в счет, так как не есть слова).

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

            Не надо смешивать всё в кучу. Пусть автор сначала хотя бы попытается объяснить, почему он пишет так.
            Его 2 аргумента ничем не обоснованы. Как показывает мой пост — первый аргумент дело вкуса. Из второго аргумента мне вообще не понятно почему я вдруг стану лучше понимать язык. Потому что мне придется помнить «правил терминирования выражений»? А оно мне вообще надо? Я не должен об этом задумываться при написании очередной строки кода. Знать — да, должен.

            Так же автор никак не аргументирует почему второе дополнение — глупый довод. Просто глупый и всё. Опять же это просто его мнение.
            • +1
              Глупый — потому что человеческий язык и язык программирования — это разные вещи.

              Представьте, придет к вам испанец и скажет: «А чего это вы не ставите ¿ в начале предложения? Мы вот ставим, это очень удобно читать и вообще правильно. А вы, недоумки, не умеете грамотно по-испански писать.»
              Такого испанца вы совершенно справедливо пошлете, потому что испанский есть испанский, а русский есть русский, и нет необходимости заимствования.
              • 0
                человеческий язык и язык программирования — это разные вещи

                С этим ни кто не спорит. Я говорил о том, что символы используются те же самые. Да и имена у них те же — точка, запятая и т.д.
                И если говорить только о правилах, касаемых знаков препинания, то они едины для всех — не нужно ничего заимствовать, да и код это не портит.

                Я говорю так не потому, что мне это кто-то рассказал, а потому что однажды я сам обратил на это внимание. Единообразие важно.
                • 0
                  Я же написал, что как раз таки знаки препинания отнюдь не едины для всех.
  • +4
    Язык программирования — это способ воплощать идеи в реальность. Чем этот способ проще, прямее и удобнее, тем лучше.

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

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

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

    Касательно топика.

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

    Знать те два с половиной случая, когда переводы строк в JS опасны — придется. Это недостаток языка. Не слишком приятный, но терпимый.

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

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

    В то же время, отлично понимаю раздражение автора. Люди, учащиеся на шаманских ресурсах, которых развелось сверх меры, никогда не заглядывающие ни в спеку, ни в действительно хорошие примеры кода, влегкую выбешивают своими суевериями )
    • –1
      Это питон то, с его «There should be one--and preferably only one--obvious way to do it»?
      • –1
        Этот принцип — тоже соглашение, он не форсируется ограничениями, встроенными в язык.
  • 0
    Столкнулся с таким стилем в исходниках MODx. Очень непривычно. Хотя может быть я не догоняю всей прелести такого стиля, может объяснит кто-нибудь в чём удобство?
    • 0
      единственный более-менее ощутимый (хоть и спорный) плюс такого подхода — удобно добавлять элементы в конец массива простым дублированием последней строки оного. при «классическом» добавлении надо будет пробежаться по всем добавленным элементам и проставить в конце точку с запятой. но, как я и писал, имхо, не особо-то это и весомый аргумент
  • 0
    автор многократно утверждает, что расстановка точки с запятой не добавляет никаких преимуществ с точки зрения самого языка. но, как мне показалось, кроме аргумента «это тоже безопасно» нет никаких доводов в пользу отсутствия точек с запятыми. «язык позволяет не ставить »;" и если вы делаете обратное с какой-то целью, — вы не понимаете языка" — не агрумент в пользу их отсутствия.
    • +1
      Мысль автора немного другая: «если вы ставите; из убеждения, что это вас обезопасит, то вы ошибаетесь»
      • 0
        ну, почему-то автор не обратил внимание на то, что у многих программистом JavaScript — во-первых, не единственный язык, а во-вторых, не первый, который они изучают.
        во всех языках, к которым я присматривался, у программиста весьма мало свободы в обращении с ";". я, например, расставляю точки с запятыми всюду потому что я так привык и это ни капли не противоречит правилам. даже python, на который я сейчас посматриваю, не может меня заставить отказаться от точки с запятой в конце строки :)
        • 0
          Почему, там есть про это раздел; посмотрите на «Хорошие причины ставить точки с запятой».
      • 0
        Ну бред же. «Безопасность» и «хаос», что использовались в письме к автору, относятся не к интерпретаторам, о которых он пишет в ответе. Это относится к людям, которые потом с этим кодом будут работать.

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

        Уменьшит ли излишнее оформление вероятность неоднозначного понимая кода другим разработчиком? Снова да.

        Так что, да, лишние точки с запятыми обезопасят. Но не от всяких IE, а прежде всего от ошибок связанных с человеческим фактором.
        • –1
          на взгляд они не сразу видны
          Давайте ставить в конце каждой строки ;;, а еще лучше ;;; // this is the end of statement!!! Тогда точно никто не проглядит.

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

          • 0
            Из npm.js:
            if (loading) return
            loading = true

            Или еще:
            if (!cb_ && typeof conf === «function») cb_ = conf, conf = {}

            Или:
            if (!er && node.toUpperCase() !== process.execPath.toUpperCase())

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

            Из этой же серии: someVar = condition1? val1: condition2? val2: val3;
            Вы знаете что тут в каком порядке исполняется и какое же будет значение someVar при каждом условии? Я — нет. Я просто никогда так не напишу. А ведь это еще очень банальный пример.

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

             

            ЗЫ:
            { exec: 0777 & (~umask)
            , file: 0666 & (~umask)
            , umask: umask }
            Вот тут лично я сразу не вижу инициализацию объекта. Скорее, три отдельных оператора. Первая мысль — «wtf». И только приглядевшись понимаю что это — объект. Ибо привычный шаблон в голове ломается сразу и по запятым, и по отступам (да-да, если открыл фигурную скобку, соизволь сделать отступ).
            • 0
              Я согласен, что приведенные вами примеры красивым кодом не назовешь. Но речь пока о точках с запятой, а не вложенных тернарных операторах.

              Если к приведенным вами примерам дописать точки с запятой, они не станут более читабельны, не так ли?:)
              • +1
                Первый же пример как раз на точку с запятой.
                • 0
                  Я не вижу там проблемы, простите.
  • 0
    мне кажется, что стиль «минимум точек с запятыми/запятые первыми» — слегка лучше; по двум причинам: потому что этот стиль лучше читается и потому что он поощряет разработчиков лучше понимать язык

    bash.org.ru/quote/415234

    Т.е. я хочу сказать, что это — не аргумент. Хотя с остальными пунктами статьи в целом согласен.
    • 0
      Эта цитата, несмотря на остроумие, тоже не аргумент, на самом деле.
      • 0
        Да. Цитата — не аргумент, а иллюстрация.
  • +1
    Интересно, это только у меня мозг ломается от такого?

    npm.config =
      { get : function (key) { return ini.get(key) }
      , set : function (key, val) { return ini.set(key, val, "cli") }
      , del : function (key, val) { return ini.del(key, val, "cli") }
      }
    • 0
      видимо, да. а что именно в этом фрагменте вам кажется сложным для восприятия?
      • 0
        мне кажется, такой код гораздо легче читается и понимается
        npm.config = {
            get: function (key) {
                return ini.get(key)
            },
            set: function (key, val) {
                return ini.set(key, val, "cli")
            },
            del: function (key, val) {
                return ini.del(key, val, "cli")
            }
        }


        а у автора npm вообще не понятно по какой логике ставятся скобки, я молчу про запятые в начале строки. причём этот «уникальный» стиль никем особо не пропагандируется, лидеры индустрии придерживаются другого стиля.
  • 0
    А зачем?

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