On 14 March 2018 at 12:10, Axel Kittenberger wrote:
Me too, IF I can use it everywhere. Not just in tables.
If it instead would be a new 'delete' and 'in' operator, you wouldn't have
this complaint, you can't use it otherwhere. IMO it's still just the
confusion you think of it as some kind of new value, which is
understandable, but it isn't.
I agree: the "looks like a value but isn't a value" nature of undef is
going to quickly go to the top of the list of "common pitfalls" if it
ever becomes part of the core language.
(Plus, having an expression of the form `<thing1> == <thing2>` which
is true but `<thing2> == <thing1>` isn't even syntactially valid is...
bound to produce some head-scratching, to put it mildly.)
The idea that the `undef` global variable is nil in Lua <5.4 and then
many programs could have the same behavior if the programmer's careful
is a clever hack, but the confusion these misleading syntactic forms
bring to the language are just not worth it IMO.
If you're writing code where you're concerned with 5.3-and-lower
compatibility, you'll have to stick with 5.3-and-lower semantics for
tables and #, and using undef won't give you anything (if anything,
you'll have to be careful that no single use of # ever relies on
undef's 5.4 behavior -- which means undef becomes useless and just
another 5.3-nil). Otherwise, if you don't care about 5.3-and-lower
compat, you'd be better off with a less confusing and more consistent
syntax, using actual operators.
I do value a lot the possibility of being able to keep writing code
that's "5.1 and up" compatible (LuaRocks is like that!). But I'd
prefer to have a syntax that doesn't work at all on 5.1-5.3 than to
have 5.4 code that runs on 5.3 (and vice-versa) but then silently
behaves differently.
I understand that the current work version's proposal of `undef` as a
semi-value is a great effort for addressing the holes-in-tables
question while keeping "5.1 and up" possible. But writing code with
`undef` for "5.1 and up" will be painful both ways: if anywhere you
forget and assume 5.4 behavior for #, your code's silently broken on
5.1-5.3; if anywhere you forget and "unset" a key with nil (which you
can do indirectly, e.g. with table.move(), so no, grepping the sources
isn't enough), you're growing a table forever and silently making a
memory leak in 5.4. I'm afraid cross-version coding in that world
would become a minefield.