Por que a maioria das linguagens de programação não aninha comentários em bloco?


18

Alguns sim, mas nenhum dos populares até onde eu sei. Há algo de ruim em aninhar comentários?

Pretendo que os comentários em bloco sejam aninhados no (pequeno) idioma em que estou trabalhando, mas gostaria de saber se isso é uma má ideia.


re algumas respostas: ohh, isso faz sentido =) Estou fazendo comentários de bloco aninhados então; embora eu tenha um estágio de lexing separado, não é o tipo limitador descrito pela SK-logic.

@Vuntic: Se você tem um estágio de lexing separado que usa coisas mais complicadas do que expressões regulares, você pode ter problemas de desempenho. Os REs são rápidos e fáceis de usar, implementando DFAs.
David Thornley

Ele pega mais erros anteriores para não permitir nidificação

4
@ David: ... de jeito nenhum. É realmente muito rápido.
amara

Sugiro que, se você deseja permitir comentários aninhados, permita que as tags de comentário inicial sejam marcadas com um token e exija que, se uma tag de comentário inicial for marcada, sua tag de comentário final deverá ser identificada de forma idêntica. Isso permitiria identificar rapidamente as tags de início / fim desequilibradas e evitar a possibilidade de erros causados ​​por tags desequilibradas não detectadas.
Supercat

Respostas:


6

Uma coisa que ninguém mencionou ainda, então vou mencionar: o desejo de aninhar comentários geralmente indica que o programador está fazendo errado.

Primeiro, vamos concordar que o único momento em que "aninhamento" ou "não aninhamento" é visível para o programador é quando ele escreve algo estruturalmente assim:

do_something();
/* comment /* nested comment */ more comment */
do_something_else();

Agora, quando isso acontece na prática? Certamente o programador não escreverá comentários aninhados que literalmente se parecem com o trecho acima! Não, na prática, quando aninhamos comentários (ou desejamos poder aninhá-los), é porque queremos escrever algo como isto:

do_something();  /* do a thing */
/* [ajo] 2017-12-03 this turned out to be unnecessary
do_something_else(); /* do another thing */
*/

E isso é ruim. Este não é um padrão que nós (como designers de linguagem) queremos incentivar! A maneira correta de escrever o trecho acima é:

do_something();  /* do a thing */

Esse código "errado", esse início falso ou o que quer que fosse, não pertence à base de código. Pertence, na melhor das hipóteses, ao histórico de controle de origem. Idealmente, você nunca escreveria o código errado para começar, certo? E se o código errado estava servindo a um propósito lá, alertando os mantenedores para não restabelecê-lo por algum motivo, bem, provavelmente é um trabalho para um comentário de código intencional e bem escrito. Tentar expressar "não faça X" apenas deixando um código antigo que faça X, mas comentado, não é a maneira mais legível ou eficaz de impedir as pessoas de fazerem X.

Tudo isso se resume a uma regra simples que você já deve ter ouvido antes: não comente o código. (Buscando essa frase vai aparecer um monte de opiniões em acordo .)

Antes que você pergunte: sim, linguagens como C, C # e C ++ já dar o programador outra ferramenta para "comment out" grandes blocos de código: #if 0. Mas essa é apenas uma aplicação específica do pré-processador C, que é uma ferramenta grande e útil por si só. Na verdade, seria extremamente difícil e especial para um idioma suportar compilação condicional com #ife ainda não suporte #if 0.


Portanto, estabelecemos que comentários aninhados são relevantes apenas quando o programador está comentando o código; e estabelecemos (por consenso de muitos programadores experientes) que comentar código é uma coisa ruim.

Para concluir o silogismo, devemos aceitar que os designers de linguagem tenham interesse em promover as Coisas Boas e em desencorajar as Coisas Ruas (assumindo que tudo o resto é igual).

No caso de comentários aninhados, tudo o resto é igual - você pode ignorar com segurança as respostas com baixa votação que afirmam que a análise aninhada de /*alguma forma seria "difícil" para o analisador. (Aninhado /*não é mais difícil do que aninhado (, que quase todos os analisadores do mundo já precisam manipular.)

Sendo assim, tudo o resto é igual, um designer de linguagem deve facilitar o agrupamento de comentários (ou seja, comentar o código) ou difícil? Lembre-se de que comentar código é uma coisa ruim.

QED


Nota de rodapé. Observe que, se você não permitir comentários aninhados,

hello /* foo*/bar.txt */ world

é um "comentário" enganoso - é equivalente a

hello bar.txt */ world

(o que provavelmente é um erro de sintaxe). Mas se você fazer permitir comentários aninhados, em seguida,

hello /* foo/*.txt */ world

é um "comentário" enganoso - é equivalente a

hello

mas deixa o comentário aberto até o final do arquivo (que novamente é quase certamente um erro de sintaxe). Portanto, nenhum dos dois lados é particularmente menos propenso a erros de sintaxe não intencionais. A única diferença está em como eles lidam com o antipadrão intencional do código comentado.


1
Eu tenho uma opinião diferente baseada apenas em fatos - eu não vi tudo (e você também não). Portanto, enquanto essas regras de ouro, como "Não comente o código", parecem boas, a vida tem seus próprios caminhos. Nesse caso em particular, eu o faço frequentemente como opção, quando testo algum novo recurso e preciso introduzir gradualmente algum código; portanto, comento o código e, em seguida, menos, menos, menos e, finalmente, tenho a peça de trabalho e eu. pode remover todos os comentários (sobre o código). Minha linguagem perfeita obviamente apoiará comentários aninhados :-).
greenoldman

@greenoldman: a maioria dos idiomas não tem comentários aninhados, mas eles têm um recurso real para "remover um bloco de código", que é menos usado do que o recurso "deixar um comentário". C's #if DEADé o exemplo canônico e mais bem projetado. Em muitos idiomas, você pode simplesmente quebrar o código morto no equivalente a if (DEAD). E em muitos IDEs, você pode realmente remover o código morto e confiar em Ctrl + Z e / ou controle de versão para recuperá-lo, se desejar. Deixando um comentário, a sequência de caracteres, qualquer que seja, cujo texto seja um monte de código morto, ainda é a pior opção para facilitar a leitura.
Quuxplusone

11

Como a maioria das implementações usa estágios de análise e análise de lexing separados, e para lexing, eles usam expressões regulares antigas simples. Os comentários são tratados como espaços em branco - ou seja, tokens ignorados e, portanto, devem ser resolvidos inteiramente em um passe lexing. A única vantagem dessa abordagem é analisar a velocidade. Várias desvantagens incluem limitações severas na sintaxe (por exemplo, a necessidade de manter um conjunto fixo de palavras-chave independentes do contexto).


3
Eu discordaria sobre 'a maioria' hoje em dia. Certamente essa é a maneira tradicional, mas sei que para C, o EDG combina o pré-processador, o lexing e a análise, e suspeito que o GCC e a Microsoft também. O benefício é que ele permite implementá-los separadamente, se necessário.
Andrew Aylett

Clang também está fazendo o mesmo. Mas isso ainda é apenas uma pequena proporção dos compiladores de idiomas populares existentes.
SK-logic

@ Neil Butterworth, dê uma olhada no mcs, javac, gcc (sim, ele remenda um lexer, mas ainda assim é um passe de lexing dedicado), clang (o mesmo que gcc), dmd, fpc e muitos outros.
SK-logic

Ninguém está usando expressões regulares em seu lexing para qualquer compilador não trivial.
Nuoji 10/01

@Nuoji - para os não triviais - com certeza. Mas aqueles que dependem de ferramentas flexíveis e similares o fazem.
SK-logic

7

É perfeitamente possível criar um lexer capaz de lidar com comentários aninhados. Quando está comendo espaço em branco, quando vê /*, pode incrementar um contador de profundidade e diminuí-lo quando vê */, e parar quando a profundidade é zero. Dito isso, eu fiz muitos analisadores e nunca achei um bom motivo para aninhar comentários.

Se os comentários puderem ser aninhados, a desvantagem é que é fácil desequilibrar suas extremidades e, a menos que você tenha um editor sofisticado, ele pode ocultar invisivelmente o código que você supõe estar lá.

Uma vantagem dos comentários que não se aninham é algo como isto:

/*
some code
more code
blah blah blah
/**/

onde você pode comentar ou remover facilmente o código removendo ou adicionando a primeira linha - uma edição em uma linha. Obviamente, se esse código em si contiver um comentário, isso será interrompido, a menos que você também permita //comentários no estilo C ++ . Então é isso que eu costumo fazer.


1
//comentários também são no estilo C99.
JAB

Como alternativa, um idioma pode especificar um início de comentário /*$token, onde identifierestá qualquer token alfanumérico, e um final de comentário token$*/. Seria relativamente simples para o tokenizer incluir código para verificar se cada marca de comentário final contém o token adequado para seu bloco de comentário inicial correspondente.
Supercat

5

Como ninguém mais o mencionou, vou listar alguns idiomas que suportam comentários aninhados: Rexx, Modula-2, Modula-3, Oberon. Apesar de todas as reclamações aqui sobre problemas de dificuldade e velocidade, nenhuma delas parece ter grandes problemas.


4
Ao que acrescento: Haskell, Frege
Ingo

Também suportado pelo Scala.
Matt R

4

Um bom ponto de aninhamento de comentários de bloco é que você pode comentar grandes porções de código facilmente (bem, quase, a menos que você tenha a sequência final do comentário do bloco em uma constante de string).

Um método alternativo é acrescentar um monte de linhas à sequência de início do comentário da linha, se você tiver um editor que a suporte.

Haskell aninhou comentários em bloco, mas a maioria das pessoas parece não perceber ou reclamar. Eu acho que isso ocorre porque as pessoas que não esperam comentários aninhados tendem a evitá-los, pois isso seria um erro lexical em outros idiomas.


3

O suporte aos comentários de bloco aninhado complica o analisador, que é mais trabalhoso e pode aumentar o tempo de compilação. Eu acho que não é um recurso muito necessário para um idioma, por isso é melhor usar o tempo e o esforço em outras melhorias e otimizações.

Na minha opinião, a simplicidade é sempre uma coisa boa no design de qualquer coisa. Lembre-se de que é mais fácil adicionar um recurso do que removê-lo. Depois de permitir comentários aninhados e existirem programas por aí, não será possível removê-los sem quebrar a compatibilidade.


1
+1 para "mais fácil adicionar um recurso do que removê-lo".
..

3
depois que você desaprova comentários aninhados, você não pode permiti-los também, porque eles quebram esses comentários:/*/**/
RiaD

2

Uma razão provável é que os comentários aninhados devem ser manipulados pelo analisador, pois o sabor das expressões regulares comumente usadas nos lexers não suporta recursão. Os mais simples podem ser eliminados como espaços em branco pelo lexer, portanto, são mais simples de implementar dessa maneira.


3
Não é o "sabor". A palavra "regular" na expressão regular exclui inerentemente recursão.
R ..

3
@R: Em matemática, com certeza. Mas na programação, temos coisas que chamamos de expressões regulares que suportam recursão.
amara

A questão é: isso é mesmo um problema? A maioria dos idiomas já precisa lidar com parênteses de aninhamento. Para citar alguns: Lisp, C, Java, Python, Ruby, Perl.
Thomas Eding

Parênteses aninhados são bons, porque as coisas dentro dos parênteses são as mesmas que as do lado de fora: tokens normais. Nos comentários, você não tem tokens, apenas texto. Você precisa conseguir combinar os tokens de comentário inicial e final para saber se 'int' é um tipo ou apenas uma palavra em um comentário. (Especialmente se você eliminar os comentários no lexer.)
Alan Shutko

2
@ThePopMachine: Tenho certeza do que afirmei, que regular tem um significado formal definido, não o significado que você está usando, e que o "regular" em "expressão regular" foi escolhido para esse significado. Ser não recursivo é um resultado de sua definição.
R ..

-1

Quem sabe? Eu acho que porque apoiar comentários aninhados é mais trabalhoso - você teria que manter uma pilha de algum tipo e porque isso complica a gramática da linguagem.


-1

Comentários aninhados significam trabalho extra para o analisador. Geralmente, quando você vê o início de um comentário, ignora tudo até o marcador de comentário final. Para oferecer suporte a comentários aninhados, você também deve analisar o texto nos comentários. O maior problema, porém, é que um programador precisa ter o cuidado de fechar todos os comentários aninhados corretamente ou isso levará a erros de compilação. A implementação correta de um compilador é algo que pode ser feito, mas acompanhar os comentários aninhados como programador é bastante suscetível a erros e irritante.


3
-1: não é verdade. Analisadores sãos não funcionam assim.
amara
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.