web-dev-qa-db-fra.com

Pourquoi les noms de variables ne peuvent-ils pas commencer par des nombres?

Il y a quelque temps, je travaillais avec un nouveau développeur C++ lorsqu'il a posé la question suivante: "Pourquoi les noms de variables ne peuvent-ils pas commencer par des nombres?"

Je ne pouvais pas trouver de réponse si ce n'est que certains nombres peuvent contenir du texte (123456L, 123456U) et que 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?
121
Jeremiah

Parce qu'alors une chaîne de chiffres serait un identifiant valide ainsi qu'un nombre valide.

int 17 = 497;
int 42 = 6 * 9;
String 1111 = "Totally text";
99
skiphoppy

Pensez-y bien:

int 2d = 42;
double a = 2d;

Qu'est-ce qu'un 2,0? ou 42?

Astuce, si vous ne l'obtenez pas, d après un nombre signifie le nombre avant qu'il ne soit un double littéral

109
Pyrolistical

C'est une convention maintenant, mais c'était au départ une exigence technique.

Auparavant, les analyseurs syntaxiques de langages tels que FORTRAN ou BASIC ne nécessitaient pas l'utilisation d'espaces. Donc, fondamentalement, les éléments suivants sont identiques:

10 V1=100
20 PRINT V1

et

10V1=100
20PRINTV1

Supposons maintenant que les préfixes numériques soient autorisés. Comment interpréteriez-vous cela?

101V=100

comme

10 1V = 100

ou comme

101 V = 100

ou comme

1 01V = 100

Donc, cela a été rendu illégal.

42
Roy Dictus

Parce que l'analyse lexicale évite les retours en arrière lors de la compilation. Une variable comme:

Apple;

le compilateur saura qu'il s'agit d'un identifiant dès qu'il rencontre la lettre 'A'. 

Cependant une variable comme:

123Apple;

le compilateur ne sera pas en mesure de décider s'il s'agit d'un numéro ou d'un identifiant tant qu'il n'a pas atteint le «a». 

34
Jiayang

Les compilateurs/analyseurs/analyseurs lexicaux étaient pour moi il y a très longtemps, mais je me souviens d'avoir eu du mal à déterminer sans ambiguïté si un caractère numérique dans l'unité de compilation représentait un littéral ou un identificateur.

Les langues où l'espace est insignifiant (comme ALGOL et le FORTRAN d'origine si mes souvenirs sont exacts) ne pouvaient pas accepter les nombres pour commencer les identificateurs pour cette raison.

Cela remonte bien avant les notations spéciales pour indiquer le stockage ou la base numérique.

13
Ken Gentle

Je conviens qu’il serait pratique de permettre aux identificateurs de commencer par un chiffre. Une ou deux personnes ont mentionné que vous pouvez contourner cette restriction en ajoutant un soulignement à votre identifiant, mais c'est vraiment moche.

Je pense qu'une partie du problème provient des littéraux numériques tels que 0xdeadbeef, qui rendent difficile la définition de règles faciles à retenir pour les identificateurs pouvant commencer par un chiffre. Une façon de le 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 à des choses étranges telles que 0xdeadpork étant autorisé, 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, j’ai le sentiment que les règles concernant les noms de variables étaient arbitraires et restrictives. Pire encore, ils étaient difficiles à retenir, alors j’ai cessé d’essayer de les apprendre. J'ai juste fait ce que je sentais bien et cela a très bien fonctionné. Maintenant que j'ai appris beaucoup plus, cela ne semble pas si mal et j'ai finalement réussi à bien l'apprendre.

7
allyourcode

C'est probablement une décision prise pour plusieurs raisons. Lorsque vous analysez le jeton, il vous suffit de 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 de la performance.

L'autre option serait de vérifier si ce n'est pas un littéral et de laisser le domaine des identificateurs comme étant l'univers moins les littéraux. Mais pour faire cela, il faudrait examiner chaque caractère de chaque jeton pour savoir comment le classer.

Il y a aussi les implications stylistiques, les identifiants étant supposés être des mnémoniques, les mots sont beaucoup plus faciles à retenir que les nombres. Lorsque beaucoup de langues originales ont été écrites, définissant les styles pour les décennies à venir, ils ne pensaient pas à remplacer "2" par "à".

6
William

Comme plusieurs personnes l'ont remarqué, il existe de nombreux documents historiques sur les formats valides pour les noms de variables. Et les concepteurs de langues sont toujours influencés par ce qu'ils savent lorsqu'ils créent de nouvelles langues. 

Cela dit, presque tout le temps qu'une langue n'autorise pas les noms de variable à commencer par des nombres, c'est parce que ce sont les règles de la conception de la langue. Souvent, c’est parce qu’une règle aussi simple facilite énormément l’analyse et l’expression de la langue. Cependant, tous les concepteurs de langage ne savent pas que c'est la vraie raison. Les outils de lexing modernes vous aident, car si vous essayez de le définir comme étant admissible, ils vous donneront des conflits d’analyse.

OTOH, si votre langue a un caractère identifiable de façon unique pour annoncer des noms de variables, il est possible de la configurer pour qu’elle commence par un nombre. Des variations de règles similaires peuvent également être utilisées pour permettre des espaces dans les noms de variables. Mais la langue résultante est susceptible de ne pas ressembler beaucoup, voire pas du tout, à une langue conventionnelle populaire. 

Pour obtenir un exemple de langage de modélisation HTML assez simple permettant aux variables de commencer par des nombres et comportant des espaces, consultez Qompose

4
staticsan

Les noms de variable ne peuvent pas commencer par un chiffre, car cela peut entraîner des problèmes tels que ceux-ci

int a = 2;
int 2 = 5;
int c = 2 * a; 

quelle est la valeur de c? est 4, ou est 10! 

un autre exemple:

float 5 = 25;
float b = 5.5;

5 est un nombre ou un objet (opérateur.). Il existe un problème similaire avec le deuxième 5.

Peut-être, il y a d'autres raisons. Donc, nous ne devrions utiliser aucun chiffre au début d'un nom de variable.

4
sbagdat

COBOL permet aux variables de commencer par un chiffre.

4
brad

La restriction est arbitraire. Divers Lisps permettent aux noms de symbole de commencer par des chiffres.

4
Kyle Jones

Parce que si vous autorisiez le mot clé et l'identifiant à commencer par des caractères numériques, le lexer (une partie du compilateur) ne pourrait pas facilement différencier le début d'un littéral numérique d'un mot clé sans devenir beaucoup plus compliqué (et plus lent).

4
Nicholas Carey

L'utilisation d'un chiffre pour commencer un nom de variable complique beaucoup la vérification des erreurs lors de la compilation ou de l'interpertation.

Permettre l'utilisation de noms de variables qui ont commencé comme un nombre causerait probablement d'énormes problèmes aux concepteurs de langage. Lors de l'analyse du code source, chaque fois qu'un compilateur/interprète rencontrait un jeton commençant par un chiffre où un nom de variable était attendu, il devait rechercher dans un ensemble de règles complexe et énorme pour déterminer si le jeton était vraiment une variable ou une erreur. . La complexité ajoutée à l'analyseur de langue ne justifie peut-être pas 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 variable. Je suis sûr que cela a été fait au moins une fois. Peut-être que quelqu'un ici a effectivement vu cela quelque part.

4
mkClark

C++ ne peut pas l'avoir parce que les concepteurs de langage en ont fait une règle. Si vous deviez créer votre propre langage, vous pourriez certainement le permettre, mais vous rencontreriez probablement les mêmes problèmes qu’ils rencontraient et décidiez de ne pas le permettre. Exemples de noms de variables susceptibles de poser problème:

0x, 2d, 5555

2
Kevin

L’un des principaux problèmes de l’atténuation des conventions syntaxiques est qu’il introduit une dissonance cognitive dans le processus de codage. Votre manque de clarté pourrait avoir une influence profonde sur votre façon de penser votre code.

Dykstra n’a-t-il pas déclaré que «l’aspect le plus important de tout outil est son effet sur son utilisateur»?

2
caving

il est facile pour un compilateur d'identifier une variable à l'aide de ASCII sur l'emplacement de la mémoire plutôt que sur son numéro.

1
Vivek

Probablement parce que cela permet à l'homme de savoir plus facilement s'il s'agit d'un numéro ou d'un identifiant, et cela est dû à la tradition. Avoir des identifiants qui pourraient commencer par un chiffre ne compliquerait pas trop les analyses lexicales.

Les identifiants commençant par un chiffre ne sont pas interdits dans toutes les langues. Dans Forth, il peut s’agir de nombres et les petits nombres entiers sont normalement définis comme des mots Forth (essentiellement des identificateurs), car il est plus rapide de lire "2" en routine pour pousser un 2 sur la pile que de reconnaître "2" en tant que nombre dont la valeur était 2. (Lors du traitement des entrées du programmeur ou du bloc de disque, le système Forth séparerait les entrées en fonction des espaces. Il essaierait de rechercher le jeton dans le dictionnaire pour voir s’il s’agissait d’un mot défini, et sinon, tenterait de le traduire en un nombre et sinon marquerait une erreur.)

1
David Thornley

Supposons que vous autorisiez les noms de symbole à commencer par des nombres. Supposons maintenant que vous souhaitiez nommer une variable 12345foobar. Comment différencieriez-vous cela de 12345? Ce n'est pas vraiment difficile à faire avec une expression régulière. Le problème est en réalité un de performance. Je ne peux pas vraiment expliquer pourquoi cela est détaillé, mais cela revient essentiellement au fait que différencier 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 de ceci ici .

1
Jason Baker

Il ne peut y avoir aucun problème avec cela quand vient en déclarant variable. Mais il y a une certaine ambiguïté quand il essaie d'utiliser cette variable ailleurs comme ceci:

let 1 = "Hello world!" print (1) print (1)

print est une méthode générique qui accepte tous les types de variables. Ainsi, dans cette situation, le compilateur ne sait pas à quoi (1) le programmeur fait référence: le 1 de la valeur entière ou le 1 qui stocke une valeur de chaîne ..__ peut-être préférable pour le compilateur dans cette situation de définir quelque chose comme ça mais quand en essayant d’utiliser ce type d’ambiguïté, apportez une erreur avec une possibilité de correction pour résoudre cette erreur et éliminez cette ambiguïté.

0
Ali Torabi

La variable peut être considérée comme une valeur également pendant la compilation par le compilateurso la valeur peut appeler la valeur encore et encore récursivement 

0
aravinth

À l’origine, c’était simplement parce qu’il est plus facile de se souvenir (vous pouvez lui donner plus de signification) des noms de variable 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 indiqueront toujours que vous êtes dans une boucle et/ou la boucle 2 est une boucle dans loop1 . Que préférez-vous (a plus de sens) en tant que 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 simplement de texte ou de chiffres (comme l'adresse $ in $), cela ne devrait vraiment pas faire de différence, car cela indiquerait au compilateur Ce qui suit doit être traité comme une variable (dans ce cas) . Dans tous les cas, cela revient à ce que les concepteurs de langage veulent utiliser comme règles pour leur langage.

0
cjtech

Le compilateur a 7 phases comme suit:

  1. Analyse lexicale
  2. Analyse de syntaxe
  3. Analyse sémantique
  4. Génération de code intermédiaire
  5. Optimisation du code
  6. Génération de code
  7. Tableau des symboles

Le backtracking est évité lors de la phase d'analyse lexicale lors de la compilation du morceau de code. La variable comme Apple, le compilateur saura tout de suite son identifiant s’il rencontre le caractère «A» de la lettre dans la phase d’analyse lexicale. Cependant, pour une variable telle que 123Apple, le compilateur ne sera pas en mesure de 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 de revenir en arrière pour passer à la phase d’analyse lexicale afin d’identifier qu’elle est une variable. Mais ce n'est pas supporté par le compilateur.

Lorsque vous analysez le jeton, il suffit de 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.

0
Harikesh

Je pense que la réponse simple est que oui, la restriction est basée sur la langue. En C++ et beaucoup d'autres, cela n'est pas possible car le langage ne le prend pas en charge. Les règles ne permettent pas cela. 

La question revient à se demander pourquoi le roi ne peut pas déplacer quatre cases à la fois aux échecs. C'est parce qu'aux échecs c'est un coup illégal. Peut-il dans un autre jeu, bien sûr. Cela dépend des règles en vigueur. 

0
kemiller2002

Le backtracking est évité en phase d'analyse lexicale lors de la compilation du morceau de code. La variable comme Apple; , le compilateur connaît immédiatement son identifiant s’il rencontre le caractère de la lettre ‘A’ dans la phase d’analyse lexicale. Cependant, une variable comme 123Apple; , le compilateur ne sera pas en mesure de décider s’il s’agit d’un numéro ou d’un identifiant jusqu’à ce qu’il atteigne «a» et il faut revenir en arrière pour passer à la phase d’analyse lexicale afin d’identifier qu’il s’agit d’une variable. Mais ce n'est pas supporté par le compilateur.

Référence

0
Angelin Nadar