• Subject: Why is nil not a valid table key?
• From: Rici Lake <lua@...>
• Date: Fri, 25 Nov 2005 23:11:49 -0500

I know, it's always been that way. But is there really a compelling reason?
```
```
This has been niggling at the back of my mind for a while. From an implementation viewpoint, there would be no problem using a special type for keys for empty Nodes. I don't believe it would slow things down at all or complicate the code (since there is already a special type for dead keys.)
```
```
I'm motivated to ask after having glanced at <http://rgrig.blogspot.com/2005/11/writing-readable-code.html>. My little solution to his challenge (which basically involves inverting a table, although that's not the way it was phrased) looks like this:
```
function firstindex(vec, first, last)
first, last = first or 1, last or #vec
local index, retval = {}, {}
for i = last, first, -1 do index[vec[i]] = i end
for i = first, last do retval[i] = index[vec[i]] end
return retval
end

```
That's not technically correct, though: vec might have a nil element in the specified range, and then line 4 will blow up. There were a couple of ways of fixing it but they all seemed to just add needless complication to a nice simple program.
```
Before people jump in with their fixes, here are mine:

1) Just make nils transparently code to nil, counting on the fact
that index[nil] will return nil on the second loop

for i = last, first, -1 do
if vec[i] ~= nil then
index[vec[i]] = i
end
end

```
2) Use a sentinel value to translate nils, in and out. 'index' itself is handy:
```
local function fixnil(val, sentinel)
if val == nil then return sentinel else return val end
end
...
for i = last, first, -1 do index[fixnil(vec[i])] = i end
for i = first, last do retval[i] = index[fixnil(vec[i])] end

```
The point isn't whether there is a workaround. There are lots. The question is why the workaround is necessary. nil is certainly in the range of foo[x]; why should it not be in the domain?
```
```
If there is a good semantic reason, that's fine. I just couldn't think of one.
```
```
(By the same token, I do think NaN's should be valid keys, even if it means using the raw bitstring.)
```

```