Насколько я знаю, некоторые делают, но не самые популярные. Есть ли что-то плохое во вложении комментариев?
Я планирую разместить блочные комментарии на (маленьком) языке, над которым я работаю, но я хотел бы знать, если это плохая идея.
Насколько я знаю, некоторые делают, но не самые популярные. Есть ли что-то плохое во вложении комментариев?
Я планирую разместить блочные комментарии на (маленьком) языке, над которым я работаю, но я хотел бы знать, если это плохая идея.
Ответы:
Одна вещь, которую еще никто не упомянул, поэтому я упомяну это: желание вкладывать комментарии часто указывает на то, что программист делает это неправильно.
Во-первых, давайте согласимся, что единственный раз, когда «вложение» или «не вложение» видимо программисту, это когда программист пишет что-то структурно подобное:
do_something();
/* comment /* nested comment */ more comment */
do_something_else();
Теперь, когда такая вещь возникает на практике? Конечно, программист не собирается писать вложенные комментарии, которые буквально похожи на приведенный выше фрагмент! Нет, на практике, когда мы вкладываем комментарии (или хотим, чтобы мы могли их вкладывать), это потому, что мы хотим написать что-то вроде этого:
do_something(); /* do a thing */
/* [ajo] 2017-12-03 this turned out to be unnecessary
do_something_else(); /* do another thing */
*/
И это плохо. Это не образец, который мы (как языковые дизайнеры) хотим поощрять! Правильный способ написания фрагмента коды выше:
do_something(); /* do a thing */
Этот «неправильный» код, этот фальстарт или что бы то ни было, не входит в кодовую базу. Это относится, в лучшем случае, к истории контроля версий. В идеале, вы бы никогда не написали неправильный код для начала, не так ли? И если неправильный код служил цели там, предупреждая сопровождающих не восстанавливать его по какой-то причине, ну, это, вероятно, работа для хорошо написанного и намеренного комментария кода. Попытка выразить «не делай X», просто оставив в некотором старом коде, который делает X, но закомментирован, не самый читаемый или эффективный способ помешать людям делать X.
Все это сводится к простому практическому правилу, которое вы, возможно, слышали раньше: не закомментируйте код. (Поиск по этой фразе повернет вверх много из мнений в соглашении .)
Перед тем, как задать вопрос: да, такие языки, как C, C # и C ++ уже дают программисту еще один инструмент для «закомментировать» большие блоки кода: #if 0
. Но это всего лишь частное применение препроцессора C, который сам по себе является большим и полезным инструментом. На самом деле для языка было бы крайне сложно и специально для него поддерживать условную компиляцию, #if
но не поддерживать ее #if 0
.
Итак, мы установили, что вложенные комментарии актуальны только тогда, когда программист комментирует код; и мы установили (благодаря консенсусу многих опытных программистов), что комментирование кода - плохая вещь.
Чтобы завершить силлогизм, мы должны принять тот факт, что разработчики языка заинтересованы в продвижении хороших вещей и предотвращении плохих вещей (при условии, что все остальное равно).
В случае вложенных комментариев, все остальное является равным - вы можете смело игнорировать низко проголосовал ответы , которые утверждают , что разбор вложенные /*
будет каким - то образом быть «трудным» для синтаксического анализа. (Вложенные /*
не сложнее, чем вложенные (
, с которыми почти каждый парсер в мире уже должен обращаться.)
Итак, при прочих равных, должен ли языковой дизайнер упростить вложение комментариев (т. Е. Комментировать код) или это сложно? Напомним, что комментирование кода - плохая вещь.
QED
Сноска. Обратите внимание, что если вы не разрешите вложенные комментарии, то
hello /* foo*/bar.txt */ world
вводящий в заблуждение «комментарий» - это эквивалентно
hello bar.txt */ world
(что, вероятно, является синтаксической ошибкой). Но если вы делаете разрешить вложенные комментарии, то
hello /* foo/*.txt */ world
вводящий в заблуждение «комментарий» - это эквивалентно
hello
но оставляет комментарий открытым до самого конца файла (что опять-таки почти наверняка является синтаксической ошибкой). Таким образом, ни один из этих способов не менее подвержен непреднамеренным синтаксическим ошибкам. Единственное отличие состоит в том, как они обрабатывают преднамеренный антипаттерн закомментированного кода.
#if DEAD
- это канонический и лучший пример. Во многих языках вы можете просто обернуть мертвый код в эквивалент if (DEAD)
. А во многих IDE вы можете фактически удалить мертвый код и использовать Ctrl + Z и / или контроль версий, чтобы вернуть его, если хотите. Оставляя комментарий, любая строка документа, чей текст представляет собой кучу мертвого кода, по-прежнему является худшим вариантом для удобства чтения.
Потому что большинство реализаций используют отдельные этапы лексизации и синтаксического анализа, а для лексирования они используют простые старые регулярные выражения. Комментарии обрабатываются как пробелы, то есть игнорируемые токены, и, таким образом, должны быть полностью решены в лексическом проходе. Единственное преимущество этого подхода - скорость разбора. Многочисленные недостатки включают серьезные ограничения синтаксиса (например, необходимость поддерживать фиксированный, независимый от контекста набор ключевых слов).
Вполне возможно создать лексер, который может обрабатывать вложенные комментарии. Когда он ест пустое пространство, когда он видит, /*
он может увеличивать счетчик глубины, уменьшать его, когда видит */
, и останавливаться, когда глубина равна нулю. Тем не менее, я сделал много парсеров, и никогда не находил веских причин для комментариев вложения.
Если комментарии могут быть вложенными, то недостатком является несбалансированность их целей, и, если у вас нет необычного редактора, он может незаметно скрыть код, который, как вы полагаете, есть.
Недостаток комментариев, которые не вкладываются, выглядит примерно так:
/*
some code
more code
blah blah blah
/**/
где вы можете легко закомментировать код, удалив или добавив первую строку - редактирование в 1 строку. Конечно, если этот код сам содержит комментарий, он сломается, если только вы не разрешите //
комментировать в стиле C ++ . Вот что я склонен делать.
//
комментарии также в стиле C99.
/*$token
, где identifier
находится любой буквенно-цифровой токен, и конец комментария token$*/
. Для токенизатора было бы относительно просто включить код для проверки того, что каждая метка конечного комментария содержит соответствующий токен для соответствующего блока начального комментария.
Поскольку никто другой не упомянул об этом, я перечислю несколько языков, которые поддерживают вложенные комментарии: Rexx, Modula-2, Modula-3, Oberon. Несмотря на все жалобы по поводу сложности и скорости, ни у одного из них нет серьезных проблем.
Хорошим моментом вложенности блочных комментариев является то, что вы можете легко закомментировать большие части кода (ну, почти, если у вас нет конечной последовательности блочного комментария в строковой константе).
Альтернативный метод состоит в том, чтобы добавить строку строки с начальной последовательностью комментария строки, если у вас есть редактор, который поддерживает это.
Haskell имеет вложенные блочные комментарии, но большинство людей, похоже, не замечают и не жалуются на это. Я предполагаю, что это потому, что люди, которые не ожидают вложенных комментариев, как правило, избегают их, так как это будет лексической ошибкой в других языках.
Поддержка вложенных комментариев к блоку усложняет синтаксический анализатор, что требует больше работы и может увеличить время компиляции. Я предполагаю, что это не очень необходимая функция для языка, поэтому лучше использовать время и усилия для других улучшений и оптимизаций.
На мой взгляд, простота всегда полезна при проектировании чего-либо. Имейте в виду, что добавить компонент проще, чем удалить его. Как только вы разрешите вложенные комментарии и есть программы, использующие их, вы не сможете удалить их, не нарушив совместимость.
/*/**/
Одна из вероятных причин заключается в том, что анализатор должен обрабатывать вложенные комментарии, поскольку разновидность регулярных выражений, обычно используемых в лексерах, не поддерживает рекурсию. Простые могут быть устранены как пробелы с помощью лексера, поэтому их проще реализовать таким образом.
Кто знает? Я думаю, потому что поддержка вложенных комментариев - это больше работы - вам придется поддерживать какой-то стек, и потому что это усложняет грамматику языка.
Вложенные комментарии означают дополнительную работу для парсера. Обычно, когда вы видите начало комментария, вы игнорируете все до конца маркера комментария. Для поддержки вложенных комментариев вы должны также проанализировать текст в комментариях. Однако самая большая проблема заключается в том, что программист должен быть осторожным, чтобы правильно закрыть все вложенные комментарии, иначе это приведет к ошибкам компиляции. Правильная реализация компилятора - это то, что можно сделать, но отслеживание вложенных комментариев, как программиста, весьма подвержено ошибкам и раздражает.