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.
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.
Respostas:
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 #if
e 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.
#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.
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).
É 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.
//
comentários também são no estilo C99.
/*$token
, onde identifier
está 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.
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.
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.
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.
/*/**/
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.
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.
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.