Why are numeric function names not allowed?

Consider the following:

$ ksh -c '1(){ echo hi;};1'
ksh: 1: invalid function name
$ dash -c '1(){ echo hi;};1'
dash: 1: Syntax error: Bad function name
$ bash -c '1(){ echo hi;};1'
bash: `1': not a valid identifier
bash: 1: command not found
$ mksh -c '1(){ echo hi;};1'
hi

Basically, I was trying to declare functions 1 and 0 which would be shorthands for true and false, but as you can see I ran into problem with using numeric names in functions. Same behavior occurs with aliases and two-digit names.

Question is "why"? Is it mandated by POSIX? or just a quirk of bourne-like shells?

See also related question to this one.


POSIX says:

2.9.5 Function Definition Command

A function is a user-defined name that is used as a simple command to call a compound command with new positional parameters. A function is defined with a "function definition command".

The format of a function definition command is as follows:

 fname ( ) compound-command [io-redirect ...]

The function is named fname; the application shall ensure that it is a name (see XBD Name) and that it is not the name of a special built-in utility. An implementation may allow other characters in a function name as an extension. The implementation shall maintain separate name spaces for functions and variables.

And:

3.235 Name

In the shell command language, a word consisting solely of underscores, digits, and alphabetics from the portable character set. The first character of a name is not a digit.

Note: The Portable Character Set is defined in detail in Portable Character Set.

So a word beginning with a digit cannot be a function name.


That is a standard in many languages to prevent confusion between mathematical operations and variables or functions or methods.

Consider:

var 1 = 100

print 1*10 //should return 10 but would instead return 1000

var x = 5
x += 1
print x //returns 105, not 6    

def 100(num)
  return num * 1000
end

var y = 10 + 100(10)
print y // returns 100010 instead of 1010

As you can see, if numbers were allowed as variable or function names, doing math later on in a program might become very confusing and you would have to come up with creative workarounds if you needed to actually do math with those numbers later on. It can also produce unexpected results in some languages. Imagine you are incrementing a number for a loop but one of the digits is already a variable equaling a string. It would immediately throw an error. If you were not the original author of the code, that error could take quite a while to find.

In a nutshell, this is why most languages do not allow you to use a number as the name of a variable or function or method or etc.


In C, consider an expression like:

1000l + 2.0f;

Is 1000l a variable or a constant? Because variable names cannot begin with a digit, it has to be a constant. This makes parsing easier and stricter (typos like 1000k can be easily caught). It's also easier to have a single rule for variables and function names, since functions can treated as variables too. Now of course, parsers are far more complex and powerful, and we have things like custom literals in C++. But back in those ancient days of prehistory, sacrificing a bit of unnecessary flexibility could make your compilation (or interpretation) times much shorter (and people still complain about C++ compilation times).

And you can see the effects of a C influence throughout the shell language, so it's not surprising that the Bourne shell (or C shell) and hence, POSIX, has restricted the class of allowed names to the same as that of C.