Why can't variable names start with numbers?

2019-01-01 02:36发布

问题:

I was working with a new C++ developer a while back when he asked the question: \"Why can\'t variable names start with numbers?\"

I couldn\'t come up with an answer except that some numbers can have text in them (123456L, 123456U) and that wouldn\'t be possible if the compilers were thinking everything with some amount of alpha characters was a variable name.

Was that the right answer? Are there any more reasons?

string 2BeOrNot2Be = \"that is the question\"; // Why won\'t this compile?

回答1:

Because then a string of digits would be a valid identifier as well as a valid number.

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


回答2:

Well think about this:

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

What is a? 2.0? or 42?

Hint, if you don\'t get it, d after a number means the number before it is a double literal



回答3:

It\'s a convention now, but it started out as a technical requirement.

In the old days, parsers of languages such as FORTRAN or BASIC did not require the uses of spaces. So, basically, the following are identical:

10 V1=100
20 PRINT V1

and

10V1=100
20PRINTV1

Now suppose that numeral prefixes were allowed. How would you interpret this?

101V=100

as

10 1V = 100

or as

101 V = 100

or as

1 01V = 100

So, this was made illegal.



回答4:

Because backtracking is avoided in lexical analysis while compiling. A variable like:

Apple;

the compiler will know it\'s a identifier right away when it meets letter \'A\'.

However a variable like:

123apple;

compiler won\'t be able to decide if it\'s a number or identifier until it hits \'a\', and it needs backtracking as a result.



回答5:

Compilers/parsers/lexical analyzers was a long, long time ago for me, but I think I remember there being difficulty in unambiguosly determining whether a numeric character in the compilation unit represented a literal or an identifier.

Languages where space is insignificant (like ALGOL and the original FORTRAN if I remember correctly) could not accept numbers to begin identifiers for that reason.

This goes way back - before special notations to denote storage or numeric base.



回答6:

It\'s likely a decision that came for a few reasons, when you\'re parsing the token you only have to look at the first character to determine if it\'s an identifier or literal and then send it to the correct function for processing. So that\'s a performance optimization.

The other option would be to check if it\'s not a literal and leave the domain of identifiers to be the universe minus the literals. But to do this you would have to examine every character of every token to know how to classify it.

There is also the stylistic implications identifiers are supposed to be mnemonics so words are much easier to remember than numbers. When a lot of the original languages were being written setting the styles for the next few decades they weren\'t thinking about substituting \"2\" for \"to\".



回答7:

I agree it would be handy to allow identifiers to begin with a digit. One or two people have mentioned that you can get around this restriction by prepending an underscore to your identifier, but that\'s really ugly.

I think part of the problem comes from number literals such as 0xdeadbeef, which make it hard to come up with easy to remember rules for identifiers that can start with a digit. One way to do it might be to allow anything matching [A-Za-z_]+ that is NOT a keyword or number literal. The problem is that it would lead to weird things like 0xdeadpork being allowed, but not 0xdeadbeef. Ultimately, I think we should be fair to all meats :P.

When I was first learning C, I remember feeling the rules for variable names were arbitrary and restrictive. Worst of all, they were hard to remember, so I gave up trying to learn them. I just did what felt right, and it worked pretty well. Now that I\'ve learned alot more, it doesn\'t seem so bad, and I finally got around to learning it right.



回答8:

Use of a digit to begin a variable name makes error checking during compilation or interpertation a lot more complicated.

Allowing use of variable names that began like a number would probably cause huge problems for the language designers. During source code parsing, whenever a compiler/interpreter encountered a token beginning with a digit where a variable name was expected, it would have to search through a huge, complicated set of rules to determine whether the token was really a variable, or an error. The added complexity added to the language parser may not justify this feature.

As far back as I can remember (about 40 years), I don\'t think that I have ever used a language that allowed use of a digit to begin variable names. I\'m sure that this was done at least once. Maybe, someone here has actually seen this somewhere.



回答9:

As several people have noticed, there is a lot of historical baggage about valid formats for variable names. And language designers are always influenced by what they know when they create new languages.

That said, pretty much all of the time a language doesn\'t allow variable names to begin with numbers is because those are the rules of the language design. Often it is because such a simple rule makes the parsing and lexing of the language vastly easier. Not all language designers know this is the real reason, though. Modern lexing tools help, because if you tried to define it as permissible, they will give you parsing conflicts.

OTOH, if your language has a uniquely identifiable character to herald variable names, it is possible to set it up for them to begin with a number. Similar rule variations can also be used to allow spaces in variable names. But the resulting language is likely to not to resemble any popular conventional language very much, if at all.

For an example of a fairly simple HTML templating language that does permit variables to begin with numbers and have embedded spaces, look at Qompose.



回答10:

Because if you allowed keyword and identifier to begin with numberic characters, the lexer (part of the compiler) couldn\'t readily differentiate between the start of a numeric literal and a keyword without getting a whole lot more complicated (and slower).



回答11:

The restriction is arbitrary. Various Lisps permit symbol names to begin with numerals.



回答12:

Variable names cannot start with a digit, because it can cause some problems like below:

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

what is the value of c? is 4, or is 10!

another example:

float 5 = 25;
float b = 5.5;

is first 5 a number, or is an object (. operator) There is a similar problem with second 5.

Maybe, there are some other reasons. So, we shouldn\'t use any digit in the beginnig of a variable name.



回答13:

COBOL allows variables to begin with a digit.



回答14:

C++ can\'t have it because the language designers made it a rule. If you were to create your own language, you could certainly allow it, but you would probably run into the same problems they did and decide not to allow it. Examples of variable names that would cause problems:

0x, 2d, 5555



回答15:

One of the key problems about relaxing syntactic conventions is that it introduces cognitive dissonance into the coding process. How you think about your code could be deeply influenced by the lack of clarity this would introduce.

Wasn\'t it Dykstra who said that the \"most important aspect of any tool is its effect on its user\"?



回答16:

Probably because it makes it easier for the human to tell whether it\'s a number or an identifier, and because of tradition. Having identifiers that could begin with a digit wouldn\'t complicate the lexical scans all that much.

Not all languages have forbidden identifiers beginning with a digit. In Forth, they could be numbers, and small integers were normally defined as Forth words (essentially identifiers), since it was faster to read \"2\" as a routine to push a 2 onto the stack than to recognize \"2\" as a number whose value was 2. (In processing input from the programmer or the disk block, the Forth system would split up the input according to spaces. It would try to look the token up in the dictionary to see if it was a defined word, and if not would attempt to translate it into a number, and if not would flag an error.)



回答17:

Suppose you did allow symbol names to begin with numbers. Now suppose you want to name a variable 12345foobar. How would you differentiate this from 12345? It\'s actually not terribly difficult to do with a regular expression. The problem is actually one of performance. I can\'t really explain why this is in great detail, but it essentially boils down to the fact that differentiating 12345foobar from 12345 requires backtracking. This makes the regular expression non-deterministic.

There\'s a much better explanation of this here.



回答18:

it is easy for a compiler to identify a variable using ASCII on memory location rather than number .



回答19:

I think the simple answer is that it can, the restriction is language based. In C++ and many others it can\'t because the language doesn\'t support it. It\'s not built into the rules to allow that.

The question is akin to asking why can\'t the King move four spaces at a time in Chess? It\'s because in Chess that is an illegal move. Can it in another game sure. It just depends on the rules being played by.



回答20:

Originally it was simply because it is easier to remember (you can give it more meaning) variable names as strings rather than numbers although numbers can be included within the string to enhance the meaning of the string or allow the use of the same variable name but have it designated as having a separate, but close meaning or context. For example loop1, loop2 etc would always let you know that you were in a loop and/or loop 2 was a loop within loop1. Which would you prefer (has more meaning) as a variable: address or 1121298? Which is easier to remember? However, if the language uses something to denote that it not just text or numbers (such as the $ in $address) it really shouldn\'t make a difference as that would tell the compiler that what follows is to be treated as a variable (in this case). In any case it comes down to what the language designers want to use as the rules for their language.



回答21:

The variable may be considered as a value also during compile time by the compiler so the value may call the value again and again recursively



回答22:

Backtracking is avoided in lexical analysis phase while compiling the piece of code. The variable like Apple; , the compiler will know its a identifier right away when it meets letter ‘A’ character in the lexical Analysis phase. However, a variable like 123apple; , compiler won’t be able to decide if its a number or identifier until it hits ‘a’ and it needs backtracking to go in the lexical analysis phase to identify that it is a variable. But it is not supported in compiler.

Reference



回答23:

The compiler has 7 phase as follows:

  1. Lexical analysis
  2. Syntax Analysis
  3. Semantic Analysis
  4. Intermediate Code Generation
  5. Code Optimization
  6. Code Generation
  7. Symbol Table

Backtracking is avoided in the lexical analysis phase while compiling the piece of code. The variable like Apple, the compiler will know its an identifier right away when it meets letter ‘A’ character in the lexical Analysis phase. However, a variable like 123apple, the compiler won’t be able to decide if its a number or identifier until it hits ‘a’ and it needs backtracking to go in the lexical analysis phase to identify that it is a variable. But it is not supported in the compiler.

When you’re parsing the token you only have to look at the first character to determine if it’s an identifier or literal and then send it to the correct function for processing. So that’s a performance optimization.



回答24:

There could be nothing wrong with it when comes into declaring variable.but there is some ambiguity when it tries to use that variable somewhere else like this :

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

print is a generic method that accepts all types of variable. so in that situation compiler does not know which (1) the programmer refers to : the 1 of integer value or the 1 that store a string value. maybe better for compiler in this situation to allows to define something like that but when trying to use this ambiguous stuff, bring an error with correction capability to how gonna fix that error and clear this ambiguity.