Pull to refresh

Comments 109

Мило. Слов многовато, суть слегка теряется (хотя может дело в том, что я просто дико устал и уже нифига не соображаю), но написано очень мило. Не знаю, настолько ли хорош стиль оригинала, но перевод получился отличный.
Спасибо. Насчет стиля — я старался передать стиль оригинала, насколько смог.
Это потому что их в оригинале много:)
UFO just landed and posted this here
UFO just landed and posted this here
программист не программист если не включает мозг.
UFO just landed and posted this here
Вы специально пишете с грамматическими ошибками, или русский не ваш родной язык?
UFO just landed and posted this here
UFO just landed and posted this here
Пишете на брейфаке, только там нужно включать мозг по-полной.
Это неплохой аргумент, на самом деле.
В русском языке «рас» — это родительный падеж множественного числа слóва «раса».
UFO just landed and posted this here
К правилам, наверное, можно еще отнести, что "\" игнорит конец строки в литералах. В результате получаем:
var text = 'Multiline \
long string \
declaration\
!';
Обратный слэш экранирует специальные символы. Вспомните:
var text = 'it\'s single quote mark!'

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

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

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

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

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

Лично мне, честно говоря, комфортнее без точек с запятой — для меня это визуальный мусор. Но я могу и так и так писать.
UFO just landed and posted this here
Автор отмечает это в разделе «Хорошие причины ставить точку с запятой».
Автор вообще не просит совсем не ставить точку с запятой. Автор просит разобраться с этим вопросом и не врать другим.
К хорошему привыкаешь быстро. У меня в истории почти ваш список (без до-диеза), плюс ещё пару раз по столько языков и все с точками с запятыми. А потом я заинтересовался Руби и добровольно повыкидывал точки с запятой из яваскриптов :)
Все стандарты кодирования вырабатываются для избежания глупых ошибок, а также для облегчения чтения кода, который будет написан в одном стиле.

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

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

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

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

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

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

Кстати, немножко оффтоп: почему так завелось, что в JS открывающая скобка остается на той же линии, а в других языках (например, в php) переносится:
//JS
if( true ) {
  doSomething();
}

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

Хотя после написания парсера php эти проблемы уже кажутся мелочью…
Угу, просто используется 2 разных начальных символа для лексера — InputElementDiv / InputElementRegexp.
Различие только в трактовке лексем начинающихся на слэш — "/" и "/=".
Собственно как побороть в ANTLR — хз. Сам я поступил довольно просто — сделал переключатель режима работы лексера — regexp/обычный, и прогонял парсер 2 раза на родительском для regexp'a выражении.
Да, оверхед, но иначе никак.
Правда пишу я, используя свои тулзы. Увы готовые совсем не подходят, ибо мне нужно «parser tree», а не AST, который и то не все генерить умеют. Да и lookahead в грамматике рулит, хз как его запилить в том же bison'e.
Не, можно сделать в однопроходном режиме. Но только если заставить лексер знать состояние парсера, чтобы правильно интерпретировать вход '/' — как начало регекспа или просто как знак деления. С точки зрения классических LL(k) это хак.
А что вы понимаете под parser tree, если не секрет?
> С точки зрения классических 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
ок, надо было жать предпросмотр :)
Ну в общем пробелы убрались и появились лишние переводы строки, но идея я думаю понятна.
Если не секрет, зачем такая работа?
Пишу утилиту для помощи в деобфускации сжатого js-кода. Там 2 этапа:
1. «Причёсываем» код, расставляя пробелы и переносы строки там где нужно.
2. Умное переименование переменных/функций/членов. Тупой Ctrl+R не пройдет по многим причинам. Основных две — scope и все танцы вокруг него (так называемое «всплытие» / постройка [[Scope]] на этапе создания функции/ ...), члены — нужно знать что это за объект и его прототип. Поэтому нужна частичная интерпретация js-кода, и учёт всех теневых влияний стандарта.

Собственно для обоих частей и нужно построение синтаксического дерева.
Причём желательно избежать 2х проходов (нам же нужно знать позиции в тексте, для переименования), поэтому нужно дерево построенное по собственным принципам — location(child[i]) < location(child[i + k]), грубо говоря. Дабы при выполнении первого этапа можно было изменять дерево на лету.
Понятно. Интересная задача.
js самый магический язык из наиболее популярных сейчас.
как мне кажется — в традиционной (в какой-то момент времени) для всех браузеров «мягкости» к ошибкам. Мол, ну забыл пользователь (закрыть элемент, добавить атрибут, поставить точку с запятой), не огорчать же его. Для начинающих может и неплоха такая магия, а вот потом — это ж сущий кошмар.
UFO just landed and posted this here
Документированность магии не меняет ее сути ;)
Интересная получилась опечатка: спорите с магией, говоря о святости.
Статья интересная, но такая расстановка запятых меня (лично меня, no offense) люто бесит. И такой код плохо читается.
Думаю, это дело привычки, на самом деле.
ИМХО.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Из 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». И только приглядевшись понимаю что это — объект. Ибо привычный шаблон в голове ломается сразу и по запятым, и по отступам (да-да, если открыл фигурную скобку, соизволь сделать отступ).
Я согласен, что приведенные вами примеры красивым кодом не назовешь. Но речь пока о точках с запятой, а не вложенных тернарных операторах.

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

bash.org.ru/quote/415234

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

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.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 вообще не понятно по какой логике ставятся скобки, я молчу про запятые в начале строки. причём этот «уникальный» стиль никем особо не пропагандируется, лидеры индустрии придерживаются другого стиля.
Sign up to leave a comment.

Articles