In Lua, nil is assuredly a value. `return type(nil) == 'nil'` is a valid program which returns `true`.
It doesn't have the semantics you're used to from other languages. I happen to prefer Lua's approach, I think the distinction between undefined and null is clunky and I'm glad that `undef` didn't make the cut in 5.4.
You presumably disagree, which is fine.
There is one rough edge I've encountered, which is down to a serious wart in the standard library: `table.insert(tab, value)` inserts the value at the end of the array portion, which in Lua we express as `#tab + 1`.
But `table.insert(tab, index, value)` is what's used to insert into another slot in the array portion. This is a serious mistake which only prevails for historical reasons.
I beg of you: never shift the meaning of parameters around when you add more of them. Nothing good will ever come of this!
As a result, `table.insert(a, b, nil)` doesn't do the same thing as `table.insert(a, b)`. In the three parameter version, `b` is an index, in the two parameter version, it's a value.
It's not possible to write this sort of monstrosity in pure Lua, where nil is well behaved; but `table.insert` is a builtin, implemented in C, or whatever the host language of your particular Lua implementation happens to be.
In C, there's a difference between a `nil` on the parameter stack, and a shorter parameter stack. A Lua programmer will never see this: passing a third `nil` or just calling a function with two parameters will have the same effect.
You can actually implement that sort of logic in pure Lua too using `...` in your parameter list and then using `select('#', ...)` in the function body. For example:
> function f(...) print(select('#', ...)) end
> f(1, 2)
2
> f(1, 2, nil)
3
I didn't mean "it is impossible to build logic incorporating the number of parameters passed to a function", but rather "there will be no difference between calling an ordinary Lua function with (a, b, nil) vs (a, b), unlike table.insert, without extensive effort"
Sooner or later, a budding Lua programmer makes an index an optional, last parameter to a function, and then passes it through to `insert`.
If what you're inserting happens to be a number, this silently does the wrong thing. Suffice to say I won't ever forget this particular wart on what's become my favorite language.
You seem to be frustrated that Lua doesn't work like one other programming language: Javascript.
That's fine. Probably shouldn't use it. The nil handling is one of my favorite things about Lua, so let me offer you an alternative: instead of being grumpy about the language not working the way you'd like, instead embrace what it is, and work with it.
On the contrary, apparently you're unaware that a ton of languages and serialization formats have ‘null’. And there's nothing special about nil in Lua, it's just called ‘undefined’ in other dynamic languages (possibly with minor differences). Lua doesn't have a proper ‘null’.
But yeah, this discussion is pointless since you're obviously not concerned either about the use-cases of exchanging data with languages that are not like C, or about keeping structures ‘schemaless’ in Lua code.
It doesn't have the semantics you're used to from other languages. I happen to prefer Lua's approach, I think the distinction between undefined and null is clunky and I'm glad that `undef` didn't make the cut in 5.4.
You presumably disagree, which is fine.
There is one rough edge I've encountered, which is down to a serious wart in the standard library: `table.insert(tab, value)` inserts the value at the end of the array portion, which in Lua we express as `#tab + 1`.
But `table.insert(tab, index, value)` is what's used to insert into another slot in the array portion. This is a serious mistake which only prevails for historical reasons.
I beg of you: never shift the meaning of parameters around when you add more of them. Nothing good will ever come of this!
As a result, `table.insert(a, b, nil)` doesn't do the same thing as `table.insert(a, b)`. In the three parameter version, `b` is an index, in the two parameter version, it's a value.
It's not possible to write this sort of monstrosity in pure Lua, where nil is well behaved; but `table.insert` is a builtin, implemented in C, or whatever the host language of your particular Lua implementation happens to be.
In C, there's a difference between a `nil` on the parameter stack, and a shorter parameter stack. A Lua programmer will never see this: passing a third `nil` or just calling a function with two parameters will have the same effect.