Je travaillais avec un nouveau développeur C ++ il y a quelque temps lorsqu'il a posé la question: "Pourquoi les noms de variables ne peuvent-ils pas commencer par des nombres?"
Je n'ai pas pu trouver de réponse, sauf que certains nombres peuvent contenir du texte (123456L, 123456U) et cela ne serait pas possible si les compilateurs pensaient que tout avec une certaine quantité de caractères alpha était un nom de variable.
Était-ce la bonne réponse? Y a-t-il d'autres raisons?
string 2BeOrNot2Be = "that is the question"; // Why won't this compile?
0
qui pousse 0 sur la pile. un autre est0=
qui vérifie si 0 est sur la pile.Réponses:
Parce qu'alors une chaîne de chiffres serait un identifiant valide ainsi qu'un nombre valide.
la source
A
-F
et se terminant parh
. Cela m'a fait trébucher la première fois que j'ai essayé de définir un label pour pointer vers les données musicales de la Two Part Invention # 13 de Bach (nom logique?Bach
).Pensez-y bien:
Qu'est-ce qu'un? 2.0? ou 42?
Astuce, si vous ne comprenez pas, d après un nombre signifie le nombre avant qu'il ne soit un double littéral
la source
d
n'est pas un suffixe littéral flottant valide en C ++. Les littéraux flottants sont des doubles par défaut, vous pouvez utiliserf
oul
si vous avez besoin d'un float ou d'un long double littéral.C'est une convention maintenant, mais cela a commencé comme une exigence technique.
Autrefois, les parseurs de langages tels que FORTRAN ou BASIC ne nécessitaient pas l'utilisation d'espaces. Donc, fondamentalement, les éléments suivants sont identiques:
et
Supposons maintenant que les préfixes numériques soient autorisés. Comment interpréteriez-vous cela?
comme
ou comme
ou comme
Donc, cela a été rendu illégal.
la source
DO 10 I=1,50
pourrait être analysé de manière ambiguë commeDO1 0I=1,50
[d'ailleurs, si l'on utilise un point au lieu d'une virgule, l'instruction devient une affectation à un variable à virgule flottante nomméeDO10I
.Parce que le retour en arrière est évité dans l'analyse lexicale lors de la compilation. Une variable comme:
le compilateur saura tout de suite qu'il s'agit d'un identifiant lorsqu'il rencontre la lettre «A».
Cependant une variable comme:
Le compilateur ne pourra pas décider s'il s'agit d'un nombre ou d'un identifiant jusqu'à ce qu'il atteigne «a», et il a donc besoin d'un retour en arrière.
la source
Compilateurs / analyseurs / analyseurs lexicaux était pour moi il y a très, très longtemps, mais je pense que je me souviens qu'il était difficile de déterminer sans ambiguïté si un caractère numérique dans l'unité de compilation représentait un littéral ou un identifiant.
Les langues où l'espace est insignifiant (comme ALGOL et le FORTRAN d'origine si je me souviens bien) ne pouvaient pas accepter les nombres pour commencer les identificateurs pour cette raison.
Cela remonte à loin - avant les notations spéciales pour désigner le stockage ou la base numérique.
la source
Je conviens qu'il serait pratique de permettre aux identifiants de commencer par un chiffre. Une ou deux personnes ont mentionné que vous pouvez contourner cette restriction en ajoutant un trait de soulignement à votre identifiant, mais c'est vraiment moche.
Je pense qu'une partie du problème vient des nombres littéraux tels que 0xdeadbeef, qui rendent difficile l'élaboration de règles faciles à retenir pour les identificateurs qui peuvent commencer par un chiffre. Une façon de faire pourrait être d'autoriser tout ce qui correspond à [A-Za-z _] + qui n'est PAS un mot-clé ou un littéral numérique. Le problème est que cela conduirait à autoriser des choses étranges comme 0xdeadpork, mais pas 0xdeadbeef. En fin de compte, je pense que nous devrions être justes envers toutes les viandes: P.
Quand j'ai appris le C pour la première fois, je me souviens avoir senti que les règles pour les noms de variables étaient arbitraires et restrictives. Pire encore, ils étaient difficiles à retenir, alors j'ai renoncé à essayer de les apprendre. J'ai juste fait ce qui me semblait juste, et cela a plutôt bien fonctionné. Maintenant que j'ai appris beaucoup plus, cela ne semble pas si mal, et j'ai finalement réussi à l'apprendre correctement.
la source
C'est probablement une décision qui est venue pour plusieurs raisons, lorsque vous analysez le jeton, vous n'avez qu'à regarder le premier caractère pour déterminer s'il s'agit d'un identifiant ou d'un littéral, puis de l'envoyer à la fonction appropriée pour le traitement. C'est donc une optimisation des performances.
L'autre option serait de vérifier si ce n'est pas un littéral et de laisser le domaine des identifiants comme l'univers moins les littéraux. Mais pour ce faire, vous devrez examiner chaque caractère de chaque jeton pour savoir comment le classer.
Il y a aussi les implications stylistiques que les identificateurs sont censés être des mnémoniques, donc les mots sont beaucoup plus faciles à retenir que les nombres. Quand beaucoup de langues originales étaient écrites, définissant les styles pour les prochaines décennies, ils ne pensaient pas à remplacer «2» par «à».
la source
Les noms de variables ne peuvent pas commencer par un chiffre, car cela peut causer des problèmes comme ci-dessous:
quelle est la valeur de c? vaut 4 ou 10!
un autre exemple:
est le premier 5 un nombre, ou est un objet (opérateur.) Il y a un problème similaire avec le second 5.
Peut-être, il y a d'autres raisons. Donc, nous ne devons utiliser aucun chiffre au début d'un nom de variable.
la source
L'utilisation d'un chiffre pour commencer un nom de variable rend la vérification des erreurs lors de la compilation ou de l'interpertation beaucoup plus compliquée.
Autoriser l'utilisation de noms de variables commençant par un nombre poserait probablement d'énormes problèmes aux concepteurs de langage. Lors de l'analyse du code source, chaque fois qu'un compilateur / interpréteur rencontrait un jeton commençant par un chiffre où un nom de variable était attendu, il devrait rechercher dans un ensemble de règles énorme et compliqué pour déterminer si le jeton était vraiment une variable ou une erreur . La complexité supplémentaire ajoutée à l'analyseur de langage peut ne pas justifier cette fonctionnalité.
Aussi loin que je me souvienne (environ 40 ans), je ne pense pas avoir jamais utilisé un langage qui permettait d'utiliser un chiffre pour commencer les noms de variables. Je suis sûr que cela a été fait au moins une fois. Peut-être que quelqu'un ici a vu ça quelque part.
la source
Comme plusieurs personnes l'ont remarqué, il y a beaucoup de bagages historiques sur les formats valides pour les noms de variables. Et les concepteurs de langage sont toujours influencés par ce qu'ils savent lorsqu'ils créent de nouveaux langages.
Cela dit, à peu près tout le temps, un langage ne permet pas aux noms de variables de commencer par des nombres parce que ce sont les règles de la conception du langage. Souvent, c'est parce qu'une règle aussi simple facilite l'analyse et le lexing du langage. Cependant, tous les concepteurs de langage ne savent pas que c'est la vraie raison. Les outils de lexing modernes sont utiles, car si vous avez essayé de le définir comme autorisé, ils vous donneront une analyse des conflits.
OTOH, si votre langue a un caractère identifiable de manière unique pour annoncer les noms de variables, il est possible de le configurer pour qu'ils commencent par un nombre. Des variantes de règles similaires peuvent également être utilisées pour autoriser des espaces dans les noms de variables. Mais le langage qui en résulte ne ressemblera probablement pas beaucoup à un langage conventionnel populaire, voire pas du tout.
Pour un exemple de langage de création de modèles HTML assez simple qui permet aux variables de commencer par des nombres et d'avoir des espaces incorporés, regardez Qompose .
la source
Parce que si vous permettiez au mot-clé et à l'identifiant de commencer par des caractères numériques, le lexer (qui fait partie du compilateur) ne pouvait pas facilement différencier le début d'un littéral numérique et d'un mot-clé sans devenir beaucoup plus compliqué (et plus lent).
la source
La restriction est arbitraire. Divers Lisps permettent aux noms de symboles de commencer par des chiffres.
la source
COBOL permet aux variables de commencer par un chiffre.
la source
C ++ ne peut pas l'avoir car les concepteurs de langage en ont fait une règle. Si vous deviez créer votre propre langage, vous pourriez certainement l'autoriser, mais vous rencontreriez probablement les mêmes problèmes qu'eux et décideriez de ne pas l'autoriser. Exemples de noms de variables qui poseraient des problèmes:
0x, 2d, 5555
la source
L'un des principaux problèmes liés à l'assouplissement des conventions syntaxiques est qu'il introduit une dissonance cognitive dans le processus de codage. La façon dont vous pensez de votre code pourrait être profondément influencée par le manque de clarté que cela introduirait.
N'est-ce pas Dykstra qui a dit que "l'aspect le plus important de tout outil est son effet sur son utilisateur"?
la source
Probablement parce que cela permet à l'humain de dire plus facilement s'il s'agit d'un numéro ou d'un identifiant, et à cause de la tradition. Avoir des identifiants qui pourraient commencer par un chiffre ne compliquerait pas tant les analyses lexicales.
Toutes les langues n'ont pas d'identificateurs interdits commençant par un chiffre. Dans Forth, ils pouvaient être des nombres, et les petits entiers étaient normalement définis comme des mots Forth (essentiellement des identificateurs), car il était plus rapide de lire "2" comme une routine pour pousser un 2 sur la pile que de reconnaître "2" comme un nombre dont la valeur était 2. (Lors du traitement de l'entrée du programmeur ou du bloc de disque, le système Forth divisait l'entrée en fonction d'espaces. Il essaierait de chercher le jeton dans le dictionnaire pour voir s'il s'agissait d'un mot défini, et sinon, il essaierait de le traduire en nombre, et sinon signalerait une erreur.)
la source
Supposons que vous ayez autorisé les noms de symboles à commencer par des nombres. Supposons maintenant que vous souhaitiez nommer une variable 12345foobar. Comment différencieriez-vous cela de 12345? Ce n'est en fait pas très difficile à faire avec une expression régulière. Le problème est en fait un problème de performance. Je ne peux pas vraiment expliquer pourquoi c'est très détaillé, mais cela se résume essentiellement au fait que la différenciation de 12345foobar de 12345 nécessite un retour en arrière. Cela rend l'expression régulière non déterministe.
Il y a une bien meilleure explication à cela ici .
la source
ifq
oudoublez
mais pasif
oudouble
? Le problème fondamental de permettre aux identificateurs de commencer par des chiffres serait qu'il existe des formes existantes de littéraux hexadécimaux et de nombres à virgule flottante qui se composent entièrement de caractères alphanumériques (les langues utiliseraient quelque chose comme $ 1234 ou h'1234 au lieu de 0x1234, et nécessiteraient des nombres comme 1E23 pour inclure un point, pourrait éviter ce problème). Notez que les tentatives d'analyse de regex C peuvent déjà être déclenchées par des choses comme0x12E+5
.il est facile pour un compilateur d'identifier une variable en utilisant ASCII sur l'emplacement mémoire plutôt que sur le nombre.
la source
Le compilateur a 7 phases comme suit:
Le backtracking est évité dans la phase d'analyse lexicale lors de la compilation du morceau de code. La variable comme Apple, le compilateur connaîtra son identifiant tout de suite quand il rencontrera la lettre «A» dans la phase d'analyse lexicale. Cependant, une variable comme 123apple, le compilateur ne pourra pas décider si c'est un nombre ou un identifiant jusqu'à ce qu'il atteigne 'a' et il a besoin de revenir en arrière pour passer dans la phase d'analyse lexicale pour identifier qu'il s'agit d'une variable. Mais il n'est pas pris en charge dans le compilateur.
Lorsque vous analysez le jeton, il vous suffit de regarder le premier caractère pour déterminer s'il s'agit d'un identificateur ou d'un littéral, puis de l'envoyer à la fonction appropriée pour le traitement. C'est donc une optimisation des performances.
la source
Je pense que la réponse simple est que c'est possible, la restriction est basée sur la langue. En C ++ et bien d'autres, ce n'est pas possible car le langage ne le prend pas en charge. Cela ne fait pas partie des règles.
La question revient à demander pourquoi le roi ne peut-il pas déplacer quatre cases à la fois dans les échecs? C'est parce qu'aux échecs, c'est un coup illégal. Peut-il dans un autre jeu sûr. Cela dépend simplement des règles jouées.
la source
À l'origine, c'était simplement parce qu'il est plus facile de se souvenir (vous pouvez lui donner plus de sens) des noms de variables sous forme de chaînes plutôt que de nombres bien que des nombres puissent être inclus dans la chaîne pour améliorer la signification de la chaîne ou permettre l'utilisation du même nom de variable mais faites-le désigner comme ayant un sens ou un contexte séparé mais proche. Par exemple, loop1, loop2, etc. vous feraient toujours savoir que vous étiez dans une boucle et / ou que la boucle 2 était une boucle dans loop1. Laquelle préférez-vous (a plus de sens) comme variable: adresse ou 1121298? Qu'est-ce qui est plus facile à retenir? Cependant, si le langage utilise quelque chose pour indiquer qu'il ne s'agit pas seulement de texte ou de nombres (comme le $ in $ address), cela ne devrait vraiment pas faire de différence car cela indiquerait au compilateur que ce qui suit doit être traité comme une variable ( dans ce cas).
la source
La variable peut être considérée comme une valeur également pendant la compilation par le compilateur afin que la valeur puisse appeler la valeur encore et encore de manière récursive
la source
Le backtracking est évité en phase d'analyse lexicale lors de la compilation du morceau de code . La variable comme Apple; , le compilateur connaîtra son identifiant tout de suite lorsqu'il rencontrera le caractère de lettre «A» dans la phase d'analyse lexicale. Cependant, une variable comme 123apple; , le compilateur ne pourra pas décider s'il s'agit d'un numéro ou d'un identifiant jusqu'à ce qu'il atteigne «a» et qu'il ait besoin d'un retour en arrière pour passer dans la phase d'analyse lexicale pour identifier qu'il s'agit d'une variable. Mais il n'est pas pris en charge dans le compilateur.
Référence
la source
Il ne pourrait y avoir rien de mal à cela lorsqu'il s'agit de déclarer une variable, mais il y a une certaine ambiguïté quand il essaie d'utiliser cette variable ailleurs comme ceci:
let 1 = "Bonjour tout le monde!" imprimer (1) imprimer (1)
print est une méthode générique qui accepte tous les types de variables. donc dans cette situation, le compilateur ne sait pas à quel (1) le programmeur se réfère: le 1 d'une valeur entière ou le 1 qui stocke une valeur de chaîne. peut-être mieux pour le compilateur dans cette situation de permettre de définir quelque chose comme ça, mais lorsque vous essayez d'utiliser ce truc ambigu, apportez une erreur avec une capacité de correction pour savoir comment corriger cette erreur et effacer cette ambiguïté.
la source