Estaba trabajando con un nuevo desarrollador de C ++ hace un tiempo cuando me hizo la pregunta: "¿Por qué los nombres de variables no pueden comenzar con números?"
No pude encontrar una respuesta, excepto que algunos números pueden tener texto (123456L, 123456U) y eso no sería posible si los compiladores estuvieran pensando que todo con cierta cantidad de caracteres alfabéticos es un nombre variable.
¿Era esa la respuesta correcta? ¿Hay más razones?
string 2BeOrNot2Be = "that is the question"; // Why won't this compile?
0
que empuja 0 a la pila. otro es0=
que verifica si 0 está en la pila.Respuestas:
Porque entonces una cadena de dígitos sería un identificador válido, así como un número válido.
fuente
A
-F
y terminaron conh
. Me tropecé la primera vez que intenté definir una etiqueta para señalar los datos musicales de la Invención n. ° 13 de Bach (¿nombre lógico?Bach
).Bueno, piensa en esto:
¿Qué es un? 2.0? o 42?
Sugerencia, si no lo obtiene, d después de un número significa el número antes de que sea un doble literal
fuente
d
no es un sufijo literal flotante válido en C ++. Los literales flotantes son dobles por defecto, puede usarf
ol
si necesita un flotante o un doble literal largo.Es una convención ahora, pero comenzó como un requisito técnico.
En los viejos tiempos, los analizadores de idiomas como FORTRAN o BASIC no requerían el uso de espacios. Entonces, básicamente, los siguientes son idénticos:
y
Ahora suponga que se permiten prefijos numéricos. ¿Cómo interpretarías esto?
como
o como
o como
Entonces, esto se hizo ilegal.
fuente
DO 10 I=1,50
podría analizarse de manera ambigua comoDO1 0I=1,50
[incidentalmente, si uno usa un punto en lugar de una coma, la declaración se convierte en una asignación a un variable de punto flotante llamadaDO10I
.Porque se evita el retroceso en el análisis léxico durante la compilación. Una variable como:
el compilador sabrá que es un identificador de inmediato cuando se encuentre con la letra 'A'.
Sin embargo, una variable como:
el compilador no podrá decidir si es un número o identificador hasta que toque 'a', y como resultado necesita retroceder.
fuente
Los compiladores / analizadores / analizadores léxicos fue hace mucho, mucho tiempo para mí, pero creo recordar que hubo dificultades para determinar sin ambigüedades si un carácter numérico en la unidad de compilación representaba un literal o un identificador.
Los idiomas donde el espacio es insignificante (como ALGOL y el FORTRAN original si no recuerdo mal) no pudieron aceptar números para comenzar identificadores por esa razón.
Esto se remonta, antes de las anotaciones especiales para denotar almacenamiento o base numérica.
fuente
Estoy de acuerdo en que sería útil permitir que los identificadores comiencen con un dígito. Una o dos personas han mencionado que puede sortear esta restricción anteponiendo un guión bajo a su identificador, pero eso es realmente feo.
Creo que parte del problema proviene de literales numéricos como 0xdeadbeef, que dificultan encontrar reglas fáciles de recordar para identificadores que pueden comenzar con un dígito. Una forma de hacerlo podría ser permitir cualquier cosa que coincida con [A-Za-z _] + que NO sea una palabra clave o un número literal. El problema es que llevaría a cosas extrañas como 0xdeadpork permitido, pero no 0xdeadbeef. En última instancia, creo que deberíamos ser justos con todas las carnes: P.
Cuando estaba aprendiendo C por primera vez, recuerdo sentir que las reglas para los nombres de variables eran arbitrarias y restrictivas. Lo peor de todo, eran difíciles de recordar, así que dejé de tratar de aprenderlos. Simplemente hice lo que me pareció bien y funcionó bastante bien. Ahora que he aprendido mucho más, no parece tan malo, y finalmente pude aprenderlo bien.
fuente
Es probable que se haya tomado una decisión por varias razones, cuando analiza el token solo tiene que mirar el primer carácter para determinar si es un identificador o literal y luego enviarlo a la función correcta para su procesamiento. Entonces esa es una optimización de rendimiento.
La otra opción sería verificar si no es un literal y dejar que el dominio de los identificadores sea el universo menos los literales. Pero para hacer esto, tendría que examinar cada carácter de cada ficha para saber cómo clasificarlo.
También existe la implicación estilística que se supone que los identificadores son mnemónicos, por lo que las palabras son mucho más fáciles de recordar que los números. Cuando se escribieron muchos de los idiomas originales estableciendo los estilos para las próximas décadas, no estaban pensando en sustituir "2" por "a".
fuente
Los nombres de las variables no pueden comenzar con un dígito, porque puede causar algunos problemas, como a continuación:
¿Cuál es el valor de c? es 4 o es 10!
otro ejemplo:
es el primer 5 un número, o es un objeto (operador.) Hay un problema similar con el segundo 5.
Tal vez, hay algunas otras razones. Por lo tanto, no debemos usar ningún dígito al comienzo de un nombre de variable.
fuente
El uso de un dígito para comenzar un nombre de variable hace que la verificación de errores durante la compilación o la interacción sea mucho más complicada.
Permitir el uso de nombres de variables que comenzaron como un número probablemente causaría grandes problemas a los diseñadores de idiomas. Durante el análisis del código fuente, cada vez que un compilador / intérprete encuentra un token que comienza con un dígito donde se esperaba un nombre de variable, tendría que buscar a través de un conjunto enorme y complicado de reglas para determinar si el token era realmente una variable o un error . La complejidad añadida al analizador de idiomas puede no justificar esta característica.
Hasta donde puedo recordar (alrededor de 40 años), no creo que alguna vez haya usado un lenguaje que permitiera el uso de un dígito para comenzar nombres variables. Estoy seguro de que esto se hizo al menos una vez. Tal vez, alguien aquí ha visto esto en alguna parte.
fuente
Como varias personas han notado, hay mucho bagaje histórico sobre formatos válidos para nombres de variables. Y los diseñadores de idiomas siempre están influenciados por lo que saben cuando crean nuevos idiomas.
Dicho esto, casi todo el tiempo un idioma no permite que los nombres de variables comiencen con números es porque esas son las reglas del diseño del lenguaje. A menudo se debe a que una regla tan simple hace que el análisis del lenguaje sea mucho más fácil. Sin embargo, no todos los diseñadores de idiomas saben que esta es la verdadera razón. Las herramientas de lexing modernas ayudan, porque si tratas de definirlo como permisible, te darán conflictos de análisis.
OTOH, si su idioma tiene un carácter identificable para anunciar nombres de variables, es posible configurarlo para que comiencen con un número. También se pueden usar variaciones de reglas similares para permitir espacios en nombres de variables. Pero es probable que el lenguaje resultante no se parezca mucho a ningún lenguaje convencional popular, si es que lo hace.
Para ver un ejemplo de un lenguaje de plantillas HTML bastante simple que permite que las variables comiencen con números y tengan espacios incrustados, consulte Qompose .
fuente
Porque si permitía que la palabra clave y el identificador comenzaran con caracteres numéricos, el lexer (parte del compilador) no podría diferenciar fácilmente entre el inicio de un literal numérico y una palabra clave sin volverse mucho más complicado (y más lento).
fuente
La restricción es arbitraria. Varios Lisps permiten que los nombres de los símbolos comiencen con números.
fuente
COBOL permite que las variables comiencen con un dígito.
fuente
C ++ no puede tenerlo porque los diseñadores de lenguaje lo convirtieron en una regla. Si creara su propio idioma, ciertamente podría permitirlo, pero probablemente se encontraría con los mismos problemas que ellos y decidiría no permitirlo. Ejemplos de nombres de variables que causarían problemas:
0x, 2d, 5555
fuente
Uno de los problemas clave sobre las convenciones sintácticas relajantes es que introduce disonancia cognitiva en el proceso de codificación. La forma en que piensa sobre su código podría verse profundamente influenciada por la falta de claridad que esto introduciría.
¿No fue Dykstra quien dijo que "el aspecto más importante de cualquier herramienta es su efecto en el usuario"?
fuente
Probablemente porque hace que sea más fácil para el humano saber si es un número o un identificador, y por tradición. Tener identificadores que podrían comenzar con un dígito no complicaría demasiado los escaneos léxicos.
No todos los idiomas tienen identificadores prohibidos que comienzan con un dígito. En Forth, podrían ser números, y los enteros pequeños normalmente se definían como palabras Forth (esencialmente identificadores), ya que era más rápido leer "2" como una rutina para empujar un 2 en la pila que reconocer "2" como un número cuyo valor era 2. (Al procesar la entrada del programador o del bloque de disco, el sistema Forth dividiría la entrada de acuerdo con los espacios. Intentaría buscar el token en el diccionario para ver si era una palabra definida, y si no, intentaría traducirlo a un número, y si no, marcaría un error).
fuente
Supongamos que permitiste que los nombres de los símbolos comenzaran con números. Ahora suponga que desea nombrar una variable 12345foobar. ¿Cómo diferenciarías esto de 12345? En realidad no es terriblemente difícil de hacer con una expresión regular. El problema es en realidad uno de rendimiento. Realmente no puedo explicar por qué esto es con gran detalle, pero esencialmente se reduce al hecho de que diferenciar 12345foobar de 12345 requiere retroceder. Esto hace que la expresión regular no sea determinista.
Hay una explicación mucho mejor de esto aquí .
fuente
ifq
odoublez
pero noif
odouble
? El problema fundamental al permitir que los identificadores comiencen con dígitos sería que existen formas existentes de literales hexadecimales y números de punto flotante que consisten completamente en caracteres alfanuméricos (los idiomas usarían algo como $ 1234 o h'1234 en lugar de 0x1234, y requieren números como 1E23 para incluir un período, podría evitar ese problema). Tenga en cuenta que los intentos de análisis de expresiones regulares C ya pueden ser disparados por cosas como0x12E+5
.es fácil para un compilador identificar una variable usando ASCII en la ubicación de la memoria en lugar de un número.
fuente
El compilador tiene 7 fases de la siguiente manera:
Se evita el retroceso en la fase de análisis léxico al compilar el fragmento de código. La variable como Apple, el compilador sabrá que es un identificador de inmediato cuando se encuentre con el carácter de letra 'A' en la fase de análisis léxico. Sin embargo, una variable como 123apple, el compilador no podrá decidir si es un número o identificador hasta que toque 'a' y necesite retroceder para pasar a la fase de análisis léxico para identificar que es una variable. Pero no es compatible con el compilador.
Cuando analiza el token, solo tiene que mirar el primer carácter para determinar si es un identificador o literal y luego enviarlo a la función correcta para su procesamiento. Entonces esa es una optimización de rendimiento.
fuente
Creo que la respuesta simple es que puede, la restricción está basada en el lenguaje. En C ++ y muchos otros no puede porque el lenguaje no lo admite. No está integrado en las reglas para permitir eso.
La pregunta es similar a preguntar por qué el Rey no puede moverse cuatro espacios a la vez en Ajedrez. Es porque en el ajedrez es un movimiento ilegal. Puede en otro juego seguro. Solo depende de las reglas que se están jugando.
fuente
Originalmente era simplemente porque es más fácil recordar (puede darle más significado) nombres de variables como cadenas en lugar de números, aunque los números se pueden incluir dentro de la cadena para mejorar el significado de la cadena o permitir el uso del mismo nombre de variable, pero haga que se designe como un significado o contexto separado pero cercano. Por ejemplo, loop1, loop2, etc., siempre le permitirán saber que estaba en un loop y / o que el loop 2 era un loop dentro de loop1. ¿Cuál preferiría (tiene más significado) como variable: dirección o 1121298? ¿Cuál es más fácil de recordar? Sin embargo, si el lenguaje usa algo para denotar que no es solo texto o números (como la dirección $ en $), realmente no debería hacer una diferencia, ya que eso le diría al compilador que lo que sigue debe ser tratado como una variable ( en este caso).
fuente
El compilador puede considerar la variable como un valor también durante el tiempo de compilación, por lo que el valor puede llamar al valor una y otra vez de forma recursiva
fuente
Se evita el retroceso en la fase de análisis léxico al compilar el fragmento de código . La variable como Apple; , el compilador sabrá que es un identificador de inmediato cuando se encuentre con el carácter de letra 'A' en la fase de Análisis léxico. Sin embargo, una variable como 123apple; , el compilador no podrá decidir si es un número o un identificador hasta que toque 'a' y necesite retroceder para pasar a la fase de análisis léxico para identificar que es una variable. Pero no es compatible con el compilador.
Referencia
fuente
No puede haber nada de malo cuando se trata de declarar la variable, pero hay cierta ambigüedad cuando se trata de usar esa variable en otro lugar como este:
let 1 = "¡Hola mundo!" imprimir (1) imprimir (1)
print es un método genérico que acepta todos los tipos de variables. entonces, en esa situación, el compilador no sabe a qué (1) se refiere el programador: el 1 de valor entero o el 1 que almacena un valor de cadena. tal vez sea mejor para el compilador que en esta situación permita definir algo así, pero cuando intente usar estas cosas ambiguas, traiga un error con capacidad de corrección sobre cómo solucionar ese error y eliminar esta ambigüedad.
fuente