Pourquoi la plupart des langages de programmation n'imbriquent-ils pas les commentaires de bloc?

18

Quelques-uns le font, mais aucun des plus populaires pour autant que je sache. Y a-t-il quelque chose de mal à imbriquer des commentaires?

Je prévois d'avoir des commentaires de bloc imbriqués dans la (petite) langue sur laquelle je travaille, mais je voudrais savoir si c'est une mauvaise idée.

amara
la source
re quelques réponses: ohh, cela a du sens =) Je fais alors totalement des commentaires de blocs imbriqués; bien que j'aie une étape de lexing distincte, ce n'est pas le type de SK-logique limitant décrit.
@Vuntic: Si vous avez une étape de lexing distincte qui utilise des choses plus compliquées que les expressions régulières, vous pouvez avoir des problèmes de performances. Les RE sont rapides et faciles à utiliser grâce à la mise en œuvre des DFA.
David Thornley
Il détecte plus d'erreurs plus tôt pour ne pas autoriser l'imbrication
4
@David: ... pas du tout. C'est vraiment très rapide.
amara
Je suggérerais que si vous souhaitez autoriser les commentaires imbriqués, vous permettez aux balises de début de commentaire d'être marquées avec un jeton, et exigez que si une balise de début de commentaire est ainsi marquée, sa balise de fin de commentaire doit être marquée de manière identique. Cela permettrait d'identifier rapidement les balises de début / fin non équilibrées et d'éviter la possibilité de bogues causés par des balises non équilibrées non détectées.
supercat

Réponses:

6

Une chose que personne n'a encore mentionnée, je vais donc la mentionner: le désir d'imbriquer des commentaires indique souvent que le programmeur fait mal.

Tout d'abord, convenons que le seul moment où "l'imbrication" ou "non imbrication" est visible pour le programmeur est lorsque le programmeur écrit quelque chose de structurellement comme ceci:

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

Maintenant, quand une telle chose arrive-t-elle dans la pratique? Le programmeur n'écrira certainement pas des commentaires imbriqués qui ressemblent littéralement à l'extrait ci-dessus! Non, en pratique lorsque nous imbriquons des commentaires (ou souhaitons pouvoir les imbriquer), c'est parce que nous voulons écrire quelque chose comme ceci:

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

Et c'est MAUVAIS. Ce n'est pas un modèle que nous (en tant que concepteurs de langues) voulons encourager! La bonne façon d'écrire l'extrait ci-dessus est:

do_something();  /* do a thing */

Ce "mauvais" code, ce faux départ ou quoi que ce soit, n'appartient pas à la base de code. Il appartient, au mieux, à l'histoire du contrôle de source. Idéalement, vous n'écririez jamais le mauvais code pour commencer, non? Et si le mauvais code servait un but là-bas, en avertissant les responsables de ne pas le rétablir pour une raison quelconque, eh bien, c'est probablement un travail pour un commentaire de code bien écrit et intentionnel. Essayer d'exprimer "ne faites pas X" en laissant simplement dans un ancien code qui fait X, mais commenté, n'est pas le moyen le plus lisible ou efficace d'empêcher les gens de faire X.

Tout cela se résume à une simple règle empirique que vous avez peut-être déjà entendue auparavant: ne commentez pas le code. ( La recherche de cette phrase tournera un grand nombre d' opinions en accord .)

Avant de vous demander: oui, langages tels que C, C # et C ++ donnent déjà le programmeur un autre outil pour « commentaire » de gros blocs de code: #if 0. Mais ce n'est qu'une application particulière du préprocesseur C, qui est un outil important et utile à part entière. Il serait en fait extrêmement difficile et spécial pour un langage de prendre en charge la compilation conditionnelle avec #ifet pourtant pas de support #if 0.


Nous avons donc établi que les commentaires imbriqués ne sont pertinents que lorsque le programmeur commente du code; et nous avons établi (via le consensus de nombreux programmeurs expérimentés) que commenter le code est une mauvaise chose.

Pour compléter le syllogisme, nous devons accepter que les concepteurs de langage ont intérêt à promouvoir les bonnes choses et à décourager les mauvaises choses (en supposant que tout le reste est égal).

Dans le cas des commentaires imbriqués, tout le reste est égal - vous pouvez ignorer en toute sécurité les réponses à faible vote qui prétendent que l'analyse imbriquée /*serait en quelque sorte «difficile» pour l'analyseur. (Les imbriqués /*ne sont pas plus difficiles que les imbriqués (, que presque tous les analyseurs du monde doivent déjà gérer.)

Donc, toutes choses étant égales par ailleurs, un concepteur de langage devrait-il faciliter l' imbrication des commentaires (c.-à-d. Commenter le code), ou difficile? Rappelons que commenter le code est une mauvaise chose.

QED


Note de bas de page. Notez que si vous n'autorisez pas les commentaires imbriqués,

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

est un "commentaire" trompeur - il équivaut à

hello bar.txt */ world

(ce qui est probablement une erreur de syntaxe). Mais si vous faites autoriser les commentaires imbriqués, puis

hello /* foo/*.txt */ world

est un "commentaire" trompeur - il équivaut à

hello

mais laisse le commentaire ouvert jusqu'à la fin du fichier (ce qui est certainement une erreur de syntaxe). Donc, aucune des deux méthodes n'est particulièrement moins sujette aux erreurs de syntaxe involontaires. La seule différence réside dans la façon dont ils gèrent l' anti-motif intentionnel du code mis en commentaire.

Quuxplusone
la source
1
J'ai une opinion différente basée simplement sur des faits - je n'ai pas tout vu (et vous non plus). Ainsi, bien que ces règles d'or comme «Ne commentez pas le code» soient belles, la vie a ses propres chemins. Dans ce cas particulier, je le fais très souvent en tant que commutateur, lorsque je teste une nouvelle fonctionnalité et que je dois introduire progressivement du code, donc je commente le code, puis moins, moins, moins, et enfin j'ai une pièce de travail et je peut supprimer tous les commentaires (sur le code). Ma langue parfaite supportera bien sûr les commentaires imbriqués :-).
greenoldman
@greenoldman: La plupart des langues n'ont pas de commentaires emboîtables, mais elles auront une fonctionnalité réelle pour "supprimer un bloc de code" qui est moins utilisée que la fonctionnalité "laisser un commentaire". C #if DEADest l'exemple canonique et le mieux conçu. Dans de nombreuses langues, vous pouvez simplement envelopper le code mort dans l'équivalent de if (DEAD). Et dans de nombreux IDE, vous pouvez réellement supprimer le code mort et compter sur Ctrl + Z et / ou le contrôle de version pour le récupérer si vous le souhaitez. Laisser un commentaire, docstring, peu importe, dont le texte est un tas de code mort, est toujours la pire option pour la lisibilité.
Quuxplusone
11

Parce que la plupart des implémentations utilisent des étapes de lexing et d'analyse distinctes, et pour lexing, elles utilisent de vieilles expressions régulières simples. Les commentaires sont traités comme des espaces blancs, c'est-à-dire des jetons ignorés, et doivent donc être résolus entièrement dans une passe de lexing. Le seul avantage de cette approche est l'analyse de la vitesse. De nombreux inconvénients incluent des limitations sévères de la syntaxe (par exemple, la nécessité de maintenir un ensemble de mots-clés fixe et indépendant du contexte).

SK-logic
la source
3
Je ne serais pas d'accord sur «la plupart» de nos jours. C'est certainement la manière traditionnelle, mais je sais que pour C, EDG combine le préprocesseur, lexing et analyse, et je soupçonne que GCC et Microsoft le font aussi. L'avantage est qu'il vous permet de les implémenter séparément si vous en avez besoin.
Andrew Aylett
Clang fait de même aussi. Mais ce n'est encore qu'une infime proportion des compilateurs de langues populaires existants.
SK-logic
@Neil Butterworth, jetez un oeil à mcs, javac, gcc (oui, il patche en arrière un lexer, mais c'est toujours une passe de lexing dédiée), clang (comme gcc), dmd, fpc et bien d'autres encore.
SK-logic
Personne n'utilise d'expressions régulières dans leur lexing pour un compilateur non trivial.
Nuoji
@Nuoji - pour le non-trivial - bien sûr. Mais ceux qui comptent sur les outils flex et similaires le font.
SK-logic
7

Il est parfaitement possible de créer un lexer capable de gérer les commentaires imbriqués. Lorsqu'il mange des espaces, lorsqu'il voit, /*il peut incrémenter un compteur de profondeur, le décrémenter lorsqu'il voit */et s'arrêter lorsque la profondeur est nulle. Cela dit, j'ai fait de nombreux analyseurs et je n'ai jamais trouvé de bonne raison pour imbriquer des commentaires.

Si les commentaires peuvent être imbriqués, un inconvénient est qu'il est facile de déséquilibrer leurs extrémités, et à moins que vous n'ayez un éditeur sophistiqué, il peut masquer de manière invisible le code que vous supposez être là.

Un avantage des commentaires qui ne s'imbriquent pas est quelque chose comme ceci:

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

où vous pouvez facilement commenter le code à l'intérieur ou à l'extérieur en supprimant ou en ajoutant la première ligne - une modification sur une ligne. Bien sûr, si ce code lui-même contient un commentaire, cela se briserait, sauf si vous autorisez également des //commentaires de style C ++ . C'est donc ce que j'ai tendance à faire.

Mike Dunlavey
la source
1
//les commentaires sont également de style C99.
JAB
Alternativement, une langue pourrait spécifier un début de commentaire /*$token, où identifierest n'importe quel jeton alphanumérique et fin de commentaire token$*/. Il serait relativement simple pour le tokenizer d'inclure du code pour vérifier que chaque marque de fin de commentaire contient le jeton approprié pour son bloc de début de commentaire correspondant.
supercat
5

Puisque personne d'autre ne l'a mentionné, je vais lister quelques langues qui prennent en charge les commentaires imbriqués: Rexx, Modula-2, Modula-3, Oberon. Malgré toutes les plaintes ici concernant les problèmes de difficulté et de vitesse, aucun de ceux-ci ne semble avoir de gros problèmes.

Rugxulo
la source
4
À quoi j'ajoute: Haskell, Frege
Ingo
Pris en charge par Scala aussi.
Matt R
4

Un bon point d'imbrication des commentaires de bloc est que vous pouvez commenter facilement de grandes portions de code (enfin, presque, sauf si vous avez la séquence de fin de commentaire de bloc dans une constante de chaîne).

Une autre méthode consiste à ajouter un groupe de lignes à la séquence de début de commentaire de ligne si vous avez un éditeur qui la prend en charge.

Haskell a imbriqué des commentaires de bloc, mais la plupart des gens ne semblent pas s'en apercevoir ou s'en plaindre. Je suppose que c'est parce que les gens qui ne s'attendent pas à des commentaires imbriqués ont tendance à les éviter car ce serait une erreur lexicale dans d'autres langues.

Ingo
la source
3

La prise en charge des commentaires de blocs imbriqués complique l'analyseur, ce qui représente à la fois plus de travail et pourrait augmenter le temps de compilation. Je suppose que ce n'est pas une fonctionnalité très nécessaire pour une langue, il est donc préférable d'utiliser le temps et l'effort sur d'autres améliorations et optimisations.

À mon avis, la simplicité est toujours une bonne chose dans la conception de quoi que ce soit. Gardez à l'esprit qu'il est plus facile d'ajouter une fonctionnalité que de la supprimer. Une fois que vous autorisez les commentaires imbriqués et que des programmes l'utilisent, vous ne pourrez plus les supprimer sans rompre la compatibilité.

alexrs
la source
1
+1 pour "plus facile d'ajouter une fonctionnalité que de la supprimer".
R .. GitHub STOP HELPING ICE
3
une fois que vous interdisez les commentaires imbriqués, vous ne pouvez pas les autoriser également car cela cassera ces commentaires:/*/**/
RiaD
2

Une raison probable est que les commentaires imbriqués doivent être traités par l'analyseur, car la saveur des expressions régulières couramment utilisées dans les lexers ne prend pas en charge la récursivité. Les simples peuvent être éliminés en tant qu'espaces par le lexer, ils sont donc plus simples à implémenter de cette manière.

hammar
la source
3
Ce n'est pas la "saveur". Le mot "régulier" dans l'expression régulière exclut par nature la récursivité.
R .. GitHub STOP HELPING ICE
3
@R: En mathématiques, bien sûr. Mais en programmation, nous avons des choses que nous appelons des expressions rationnelles qui prennent en charge la récursivité.
amara
La question est: est-ce même un problème? La plupart des langues doivent déjà gérer les parenthèses d'imbrication. Pour n'en nommer que quelques-uns: Lisp, C, Java, Python, Ruby, Perl.
Thomas Eding
Les parenthèses imbriquées sont très bien, car les choses à l'intérieur des parenthèses sont les mêmes que les choses à l'extérieur: des jetons normaux. Dans les commentaires, vous n'avez pas de jetons, vous avez juste du texte. Vous devez pouvoir faire correspondre les jetons de commentaire de début et de fin afin de savoir si «int» est un type ou simplement un mot dans un commentaire. (Surtout si vous éliminez les commentaires dans le lexer.)
Alan Shutko
2
@ThePopMachine: Je suis sûr de ce que j'ai dit, que régulier a une signification formelle définie, pas la signification que vous utilisez, et que le "régulier" dans "expression régulière" a été choisi pour cette signification. Être non récursif est un résultat de sa définition.
R .. GitHub STOP HELPING ICE
-1

Qui sait? Je suppose que parce que le support des commentaires imbriqués est plus de travail - vous devrez maintenir une pile quelconque et parce que cela complique la grammaire du langage.

Neil Butterworth
la source
-1

Les commentaires imbriqués signifient un travail supplémentaire pour l'analyseur. Habituellement, lorsque vous voyez le début d'un commentaire, vous ignorez tout jusqu'au marqueur de commentaire de fin. Pour prendre en charge les commentaires imbriqués, vous devez également analyser le texte dans les commentaires. Le plus gros problème, cependant, est qu'un programmeur doit veiller à fermer correctement tous les commentaires imbriqués, sinon cela entraînera des erreurs de compilation. La mise en œuvre correcte d'un compilateur est quelque chose qui peut être fait, mais le suivi des commentaires imbriqués en tant que programmeur est assez sujet aux erreurs et irritant.

Gus
la source
3
-1: pas vrai. Les analyseurs sensés ne fonctionnent pas comme ça.
amara