lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Rici Lake wrote:
> I know, it's always been that way. But is there really a compelling 
> reason?

Because nil is different. The sole reason for its existence is
to signal special conditions and to be treated differently when
received. It behaves just like any other object under many
circumstances -- but this is deceiving.

Table traversal is a good example: one needs _some_ way to signal
the end of the traversal. Many languages offer idioms for this,
but most of them have needlessly complicated solutions:

E.g. one particular language throws a special exception at the
end of the traversal. Then it has to go to great lengths to catch
this exception in the iteration idiom (and rethrow all others).
One word: sloooow.

Another notable language requires you to explicitly check for the
end of the iteration with an extra function call. So you need to
pay the overhead of two function calls per iteration step. This
is inconvenient (slow) for some iterators, too. Another amazingly
similar language hides all this behind a language idiom, but
still has to pay the same overhead.

A compromise seen in some languages is to return an extra flag
that signals the end of the iteration. Would be simple in Lua
(which has multiple return values), but gets ugly in most other
languages. Close, but no cigar.

Lua signals the end of a table traversal with a nil key. This is
both simple and efficient.

Of course this more or less precludes having nil table keys. But
hey, that's the contract -- nil is different. That's what it was
designed for.