Most programming languages appear to be designed to not allow one to declare an identifier that starts with a number. I was just curious to know the reason. I have already searched the web, but couldn't find a satisfactory explanation.
- Anybody can ask a question
- Anybody can answer
- The best answers are voted up and rise to the top
In C/C++, a number followed by a letter is considered to be a numeric constant and the string that follows, qualifies the type of the constant. So for example (these are VC++, not sure how standard they are):
So a) it is easier for the lexer as Daniel said but also b) it makes an explicit distinction since 0y might be a variable but 0u would never be. Plus other qualifiers, like "i64" were added way later than "l" or "u" and they want to keep the option open of adding more if needed.
The convenience of the people implementing the lexer. (No, seriously, that is about it. Various languages have other reasons, but it ultimately comes down to that.)
Consider the following 2 cases:
Lets assume that an identifier could begin with a number.
So a statement like below would be valid (since an identifier can have 1 or more characters) :
When I try to use the above variable in a program, it'll result in compiler ambiguity:
In the statement
As opposed to the example above, lets assume that a language were to actually allow identifiers starting with a number while still disallowing numerals being used as identifiers. This can cause the following issues:
Making this restriction will prevent the programmer from using numbers as identifier names.
For the most part this has nothing to do with making it easy for the compiler writers and parsing efficiency, but, more to do with designing a syntax that encourages clear readable and unambiguous code.
Its the language designers thought it would be nice to be able to write numeric literals like the number 1 as just plain 1 .
It would be quite possible to design a language syntax where numeric literals were quoted in some way for example tildas so the numberic literal for number one was encoded as ~1~ and anything not a keyword and not enclosed in quotes was treated as a variable name.
So you could code statements like:
Whatever syntax you choose ambiguous and hard to follow code is unavoidable.
The C language and most of the "curly brackets" languages descended from C also thought it a good idea to allow programmers to code Octal and Hexadecimal literals directly, and, to specify the type of the literal if this was important. So
So even if you allowed variable names start with a number followed by a combination of numbers and letter that included at least one letter you would present the programmer with the problem of deciding whether a given group formed a variable name or a numeric literal so
Such ambiguity would not help anyone writing or reading a program.
For a closely related real world example you could look at PL/1 language whose designers thought that being able to use keywords as variable names was a good idea so that:
Is valid code which compiles and executes.
Fortran had a huge effect on how later languages were designed. Early on (some of these problems have since been fixed) Fortran had almost no rules restricting what name you could give to an identifier. This made the language extremely difficult to parse both for compilers and for programmers. Here's one classic example:
Here I've marked the "language key words" with K and the identifiers (variable names) I. Given that there's no difference in spelling, I think you can probably understand how confusing this could be. Of course, this is an extreme example, and it's unlikely anybody ever wrote code quite like this on purpose. Sometimes people did "recycle" language key words as identifier names though -- and in a lot of cases a simple typo could result in code that the language spec said should be parsed this way, even though it wasn't intended at all. For another well-known example, compare this:
The first is a do loop -- iterating a block of code 10 times. The second, however, has had the comma changed to a decimal point, so it's assigning the value
This also meant that writing a Fortran parser was relatively difficult -- you couldn't be certain that the
After a few years of this, language designers (most of them anyway) went toward the opposite extreme -- restricting nearly everything about the language as much as possible without the users complaining too much.
Early BASIC, for example, basically said you couldn't even use a key word as part of an identifier -- for example,
Likely this convention has evolved from very early historical language design decisions, as on early machines the entire compiler, including lexical analysis, had to run in a few kWords, less memory than even just the first-level processor data cache on current mobile devices, so the allowed variable names were very limited, and had to be easy to distinguish from numeric constants in very few op codes.
Thus, the convention became what generations of programmers are used to.
It's not a logically required rule for programming language but just the convention used by many language designers.
I can design radically different language that allow all character for identifiers. For all code lines, first 20 character will describe the statement type then next 20 character will define the first symbol for the statement, and next 20 character is operand for the statement. This language will be executed on a stack processor.
This code could be translated in C as below:
That's all. It's meaningless and the no-number-in-identifiers rule is also pointless in logical ground.
In addition to "convenience for the lexer", I think it is also worth considering "convenience for the reader".
When reading code, you need to quickly and repeatedly identify which words are identifiers, and which are numbers. Looking for a digit at the beginning is easier on our visual pattern-matching; it would be a chore if we had to carefully check all the characters to make sure.
The answer to this question lies in automata or more precisely finite automata that defines the regular expression. The rule is...compilers need exact algorithms or rules to decide at every character that they parse. If identifiers were allowee to start with a number then the compiler will be in a fix..about the nature of the token coming...will it be a number or an identifier...and as compilers cant backtrack to earlier positions...so..to make it clear to the compiler that the coming token is precisely an identifier or a number...this restriction is there...coz of this...compiler knows just by scanning the first character that the coming token is an identifier or a number.