¿Por qué la mayoría de los lenguajes de programación no anidan los comentarios de bloque?

18

Algunos lo hacen, pero no ninguno de los populares, que yo sepa. ¿Hay algo malo en anidar comentarios?

Planeo que los comentarios de bloque aniden en el idioma (pequeño) en el que estoy trabajando, pero me gustaría saber si es una mala idea.

amara
fuente
Hay algunas respuestas: ohh, eso tiene sentido =) Estoy haciendo totalmente comentarios de bloque anidados entonces; aunque tengo una etapa de lexing separada, no es el tipo limitante descrito por SK-logic.
@Vuntic: si tiene una etapa lexing separada que usa cosas más complicadas que las expresiones regulares, puede tener problemas de rendimiento. Los RE son rápidos y fáciles de usar mediante la implementación de DFA.
David Thornley
44
@David: ... en absoluto. En realidad es muy rápido.
amara
Sugeriría que si desea permitir comentarios anidados, permita que las etiquetas de comentario de inicio se marquen con un token, y requiera que si una etiqueta de comentario de inicio se marca así, su etiqueta de comentario final debe marcarse de manera idéntica. Eso permitiría identificar rápidamente las etiquetas de inicio / fin no balanceadas y evitaría la posibilidad de errores causados ​​por etiquetas no balanceadas no detectadas.
supercat

Respuestas:

6

Una cosa que nadie ha mencionado todavía, así que lo mencionaré: el deseo de anidar comentarios a menudo indica que el programador está haciendo mal.

Primero, aceptemos que el único momento en que el programador puede "anidar" o "no anidar" es cuando el programador escribe algo estructuralmente como esto:

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

Ahora, ¿cuándo surge tal cosa en la práctica? ¡Ciertamente, el programador no va a escribir comentarios anidados que literalmente se vean como el fragmento anterior! No, en la práctica cuando anidamos comentarios (o deseamos poder anidarlos), es porque queremos escribir algo como esto:

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

Y esto es MALO. ¡Este no es un patrón que (como diseñadores de idiomas) queremos fomentar! La forma correcta de escribir el fragmento anterior es:

do_something();  /* do a thing */

Ese código "incorrecto", ese inicio falso o lo que sea, no pertenece a la base de código. Pertenece, en el mejor de los casos, al historial de control de fuente. Idealmente, para empezar, nunca escribirías el código incorrecto, ¿verdad? Y si el código incorrecto cumplía un propósito allí, al advertir a los encargados del mantenimiento que no lo restablecieran por alguna razón, bueno, probablemente sea un trabajo para un comentario de código bien escrito e intencional. Intentar expresar "no hagas X" simplemente dejando algún código antiguo que haga X, pero comentado, no es la forma más fácil de leer o efectiva para evitar que las personas hagan X.

Todo esto se reduce a una simple regla general que quizás hayas escuchado antes: no comentes el código. (Buscando esta frase a su vez, una gran cantidad de opiniones en el acuerdo .)

Antes de preguntar: sí, lenguajes como C, C #, C ++ y ya dan el programador otra herramienta para "comente" grandes bloques de código: #if 0. Pero esta es solo una aplicación particular del preprocesador C, que es una herramienta grande y útil por derecho propio. En realidad, sería extremadamente difícil y especial para un lenguaje admitir la compilación condicional #ify, sin embargo, no admitirlo #if 0.


Por lo tanto, hemos establecido que los comentarios anidados son relevantes solo cuando el programador comenta el código; y hemos establecido (a través del consenso de muchos programadores experimentados) que comentar el código es algo malo.

Para completar el silogismo, debemos aceptar que los diseñadores de idiomas tienen interés en promover las cosas buenas y desalentar las cosas malas (suponiendo que todo lo demás sea igual).

En el caso de los comentarios anidados, todo lo demás es igual: puede ignorar con seguridad las respuestas con bajo voto que afirman que el análisis anidado /*sería de alguna manera "difícil" para el analizador. (Los anidados /*no son más difíciles que los anidados (, que casi todos los analizadores del mundo ya deben manejar).

Entonces, si todo lo demás es igual, ¿debería un diseñador de lenguaje hacer que sea fácil anidar comentarios (es decir, comentar el código) o difícil? Recordemos que comentar el código es algo malo.

QED


Nota. Tenga en cuenta que si no permite comentarios anidados, entonces

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

es un "comentario" engañoso, es equivalente a

hello bar.txt */ world

(que probablemente sea un error de sintaxis). Pero si haces permiten comentarios anidados, a continuación,

hello /* foo/*.txt */ world

es un "comentario" engañoso, es equivalente a

hello

pero deja el comentario abierto hasta el final del archivo (que de nuevo es casi seguro un error de sintaxis). Por lo tanto, ninguna de las dos formas es particularmente menos propensa a errores de sintaxis no intencionales. La única diferencia está en cómo manejan el antipatrón intencional del código comentado.

Quuxplusone
fuente
1
Tengo una opinión diferente basada simplemente en un hecho: no vi todo (y tú tampoco). Entonces, aunque esas reglas de oro como "No comentar código" se ven bien, la vida tiene sus propios caminos. En este caso particular, lo hago muy a menudo como un interruptor, cuando pruebo alguna característica nueva y tengo que introducir gradualmente algún código, así que comento el código, luego menos, menos, menos, y finalmente tengo una pieza de trabajo y yo Puede eliminar todos los comentarios (sobre el código). Mi lenguaje perfecto, por supuesto, admitirá comentarios anidados :-).
greenoldman
@greenoldman: la mayoría de los idiomas no tienen comentarios anidables, pero tendrán alguna función real para "eliminar un bloque de código" que es menos utilizada que la función "dejar un comentario". C #if DEADes el ejemplo canónico y mejor diseñado. En muchos idiomas, puede envolver el código muerto en el equivalente de if (DEAD). Y en muchos IDEs, puede eliminar el código muerto y confiar en Ctrl + Z y / o el control de versiones para recuperarlo si lo desea. Dejar un comentario, docstring, lo que sea, cuyo texto es un montón de código muerto, sigue siendo la peor opción de legibilidad.
Quuxplusone
11

Debido a que la mayoría de las implementaciones están usando etapas separadas de lexing y parsing, y para la lexing están usando expresiones regulares simples y antiguas. Los comentarios se tratan como espacios en blanco, es decir, tokens ignorados y, por lo tanto, deben resolverse por completo en un pase lexing. La única ventaja de este enfoque es la velocidad de análisis. Numerosas desventajas incluyen limitaciones severas en la sintaxis (por ejemplo, la necesidad de mantener un conjunto fijo de palabras clave independientes del contexto).

SK-logic
fuente
3
No estaría de acuerdo con 'la mayoría' hoy en día. Ciertamente, esa es la forma tradicional, pero sé que para C, EDG combina el preprocesador, el lexing y el análisis, y sospecho que tanto GCC como Microsoft también lo hacen. El beneficio es que le permite implementarlos por separado si es necesario.
Andrew Aylett
Clang también está haciendo lo mismo. Pero eso sigue siendo solo una pequeña proporción de los compiladores de idiomas populares existentes.
SK-logic
@Neil Butterworth, eche un vistazo a mcs, javac, gcc (sí, remenda un lexer, pero aún así es un pase de lexing dedicado), clang (igual que gcc), dmd, fpc y muchos, muchos más.
SK-logic
Nadie está usando expresiones regulares en su lexing para ningún compilador no trivial.
Nuoji
@Nuoji, para los no triviales, claro. Pero aquellos que confían en flex y herramientas similares lo hacen.
SK-logic
7

Es perfectamente posible hacer un lexer que pueda manejar comentarios anidados. Cuando está comiendo espacios en blanco, cuando ve /*que puede aumentar un contador de profundidad y disminuirlo cuando ve */, y detenerse cuando la profundidad es cero. Dicho esto, he hecho muchos analizadores y nunca encontré una buena razón para anidar los comentarios.

Si los comentarios pueden anidarse, entonces un inconveniente es que es fácil desequilibrar sus extremos y, a menos que tenga un editor sofisticado, puede ocultar invisiblemente el código que supone que está allí.

Una ventaja de los comentarios que no anidan es algo como esto:

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

donde puede comentar fácilmente el código dentro o fuera quitando o agregando la primera línea, una edición de 1 línea. Por supuesto, si ese código contiene un comentario, esto se rompería, a menos que también permita //comentarios de estilo C ++ allí. Entonces eso es lo que tiendo a hacer.

Mike Dunlavey
fuente
1
//Los comentarios también son de estilo C99.
JAB
Alternativamente, un idioma podría especificar un inicio de comentario es /*$token, donde identifierhay un token alfanumérico y un final de comentario token$*/. Sería relativamente simple para el tokenizador incluir código para verificar que cada marca de comentario final contenga el token adecuado para su bloque de comentario inicial correspondiente.
supercat
5

Como nadie más lo mencionó, enumeraré algunos idiomas que admiten comentarios anidados: Rexx, Modula-2, Modula-3, Oberon. A pesar de todas las quejas aquí sobre problemas de dificultad y velocidad, ninguno de ellos parece tener grandes problemas.

Rugxulo
fuente
44
A lo que agrego: Haskell, Frege
Ingo
Apoyado por Scala también.
Matt R
4

Un buen punto de anidar comentarios de bloque es que puede comentar grandes porciones de código fácilmente (bueno, casi, a menos que tenga la secuencia final de comentario de bloque en una cadena constante).

Un método alternativo es anteponer un montón de líneas con la secuencia de inicio de comentarios de línea si tiene un editor que lo admita.

Haskell ha anidado comentarios en bloque, pero la mayoría de las personas no parecen darse cuenta o quejarse al respecto. Supongo que esto se debe a que las personas que no esperan comentarios anidados tienden a evitarlos, ya que esto sería un error léxico en otros idiomas.

Ingo
fuente
3

El soporte de comentarios de bloque anidados complica el analizador, que es más trabajo y podría aumentar el tiempo de compilación. Supongo que no es una característica muy necesaria para un idioma, por lo que es mejor usar el tiempo y el esfuerzo en otras mejoras y optimizaciones.

En mi opinión, la simplicidad siempre es buena para diseñar cualquier cosa. Tenga en cuenta que es más fácil agregar una función que eliminarla. Una vez que permita comentarios anidados y haya programas que lo usen, no podrá eliminarlos sin romper la compatibilidad.

alexrs
fuente
1
+1 para "es más fácil agregar una función que eliminarla".
R ..
3
una vez que no permita los comentarios anidados, no podrá permitirlos también porque los romperá:/*/**/
RiaD
2

Una razón probable es que los comentarios anidados deben ser manejados por el analizador, ya que el sabor de las expresiones regulares comúnmente utilizadas en lexers no admite la recursividad. Los simples pueden ser eliminados como espacios en blanco por el lexer, por lo que son más fáciles de implementar de esa manera.

hammar
fuente
3
No es el "sabor". La palabra "regular" en expresión regular excluye intrínsecamente la recursividad.
R ..
3
@R: En matemáticas, claro. Pero en la programación, tenemos cosas que llamamos expresiones regulares que admiten la recursividad.
amara
La pregunta es: ¿es esto incluso un problema? La mayoría de los idiomas ya tienen que lidiar con paréntesis de anidamiento. Por nombrar algunos: Lisp, C, Java, Python, Ruby, Perl.
Thomas Eding
Los paréntesis anidados están bien, porque las cosas dentro de los paréntesis son las mismas que las de afuera: tokens normales. En los comentarios, no tienes tokens, solo tienes texto. Debe poder hacer coincidir los tokens de comentarios de inicio y fin para saber si 'int' es un tipo o solo una palabra en un comentario. (Especialmente si elimina los comentarios en el lexer.)
Alan Shutko
2
@ThePopMachine: estoy seguro de lo que dije, que regular tiene un significado formal definido, no el significado que está utilizando, y que se eligió el "regular" en "expresión regular" para este significado. Ser no recursivo es un resultado de su definición.
R ..
-1

¿Quién sabe? Supongo que apoyar los comentarios anidados es más trabajo: tendrías que mantener una pila de algún tipo y complica la gramática del lenguaje.

Neil Butterworth
fuente
-1

Los comentarios anidados significan un trabajo extra para el analizador. Por lo general, cuando ve el comienzo de un comentario, ignora todo hasta el marcador de comentario final. Para admitir comentarios anidados, también debe analizar el texto en los comentarios. Sin embargo, el mayor problema es que un programador debe tener cuidado de cerrar todos los comentarios anidados correctamente o provocará errores de compilación. Implementar correctamente un compilador es algo que se puede hacer, pero realizar un seguimiento de los comentarios anidados como programador es bastante propenso a errores e irritante.

Gus
fuente
3
-1: no es cierto. Los analizadores sanos no funcionan así.
amara