Why can't variable names start with numbers?

C++VariablesProgramming LanguagesLanguage DesignVariable Names

C++ Problem Overview


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?

C++ Solutions


Solution 1 - C++

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";

Solution 2 - C++

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

Solution 3 - C++

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.

Solution 4 - C++

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.

Solution 5 - C++

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.

Solution 6 - C++

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.

Solution 7 - C++

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".

Solution 8 - C++

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.

Solution 9 - C++

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

Solution 10 - C++

COBOL allows variables to begin with a digit.

Solution 11 - C++

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.

Solution 12 - C++

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.

Solution 13 - C++

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).

Solution 14 - C++

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

Solution 15 - C++

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"?

Solution 16 - C++

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.

Solution 17 - C++

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.)

Solution 18 - C++

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.

Solution 19 - C++

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

Solution 20 - C++

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.

Solution 21 - C++

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.

Solution 22 - C++

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

Solution 23 - C++

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

Solution 24 - C++

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJeremiahView Question on Stackoverflow
Solution 1 - C++skiphoppyView Answer on Stackoverflow
Solution 2 - C++PyrolisticalView Answer on Stackoverflow
Solution 3 - C++Roy DictusView Answer on Stackoverflow
Solution 4 - C++JiayangView Answer on Stackoverflow
Solution 5 - C++Ken GentleView Answer on Stackoverflow
Solution 6 - C++allyourcodeView Answer on Stackoverflow
Solution 7 - C++WilliamView Answer on Stackoverflow
Solution 8 - C++sbagdatView Answer on Stackoverflow
Solution 9 - C++Kyle JonesView Answer on Stackoverflow
Solution 10 - C++bradView Answer on Stackoverflow
Solution 11 - C++mkClarkView Answer on Stackoverflow
Solution 12 - C++staticsanView Answer on Stackoverflow
Solution 13 - C++Nicholas CareyView Answer on Stackoverflow
Solution 14 - C++KevinView Answer on Stackoverflow
Solution 15 - C++cavingView Answer on Stackoverflow
Solution 16 - C++HarikeshView Answer on Stackoverflow
Solution 17 - C++David ThornleyView Answer on Stackoverflow
Solution 18 - C++Jason BakerView Answer on Stackoverflow
Solution 19 - C++VivekView Answer on Stackoverflow
Solution 20 - C++kemiller2002View Answer on Stackoverflow
Solution 21 - C++cjtechView Answer on Stackoverflow
Solution 22 - C++aravinthView Answer on Stackoverflow
Solution 23 - C++Angelin NadarView Answer on Stackoverflow
Solution 24 - C++Ali TorabiView Answer on Stackoverflow