[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Empty? No. Array? No. Has? Yes.
- From: Andrew Starks <andrew.starks@...>
- Date: Wed, 3 Jul 2013 08:41:13 -0500
On Wed, Jul 3, 2013 at 1:08 AM, Dirk Laurie <dirk.laurie@gmail.com> wrote:
> 2. I prefer to ignore most if not all of your post so that I can get
> in a reply as fast as I can type.
> 3. You're not really listening to me. Here is the same stuff again.
I sense this may be aimed at my posts, and if so, I'll admit to being
guilty of typing ahead of my brain, at times. Usually I have time to
think about this stuff at a time when I'm stuck beneath a sleeping kid
with only an iPhone in my hand. It makes for a piss-poor typing job
and a sub-optimal email client, which are reasons, not a excuses. I'll
take more time in the future. Thanks for pointing this out.
> There are many situations where the programmer, especially the
> newbie programmer, has a reasonable right to expect Lua to be able
> to tell whether a key with no useful value is just a nonsense key
> (probably a typo) or a key that forms part of the logical design
> but has no value just yet.
<snip... all stuff that is agreed to>
>
> Suggested extensions to Lua:
>
> 1. A standard sentinel value (called 'empty', 'placeholder' etc)
> maybe even having its own type.
> 2. A dedicated implementation of arrays, maybe as a new type, maybe
> as a new library, maybe dependent on non-numeric fields.
> 3. New standard functions: 'table.has' to indicate whether a key is
> legal; 'table.delete' to permanently change the legality status
> of a key.
I *read* 3 is subtly different. :) If I take Eike's words as the source:
"Because if a value does exists, it can also be nil, if it doesn't
exist, it's still nil but you can check that. You can of course not
pass "empty" to a function this way, which your idea allows, but that
can get easily around this if required through additional parameters
or functions in the API that you define yourself."
delete does not infer special status to a key value. It simply deletes
the table entry by the key's name.
>
> Non-negotiable restriction on any change:
>
> Full backward compatibility, including validity of the idiom
> t[#t]=nil for shortening a list.
#3 does not need to change any behavior in Lua.
All other values, according to the specification, have a metatable,
including numbers.
A table could have a default metatable where:
__index = function(t, i) return nil end
and perhaps, but possibly not necessary:
__newindex = function(t, i, v)
if i == nil and then
table.delete(t, i)
else
rawset(t, i, v)
end
end
This default table may or may not be accessible to the Lua user.
[There is a sort of default metatable, right now, if one imagines
ipairs, pairs, tostring, and len being predefined in a C-side
metatable.]
When a new metatable is assigned to a table, undefined values fall
through to this default table. [This would change the way Lua
currently works for metamethods, in this one case.]
Therefore, all default libraries could behave in the same way,
although internally they would work on undefined values, not nil
values. The Lua user would not know the difference, thanks to the
above default behavior of tables.
Yet in fact, things could be made to behave differently (and more
clearly) if such behavior is needed:
setmetatable(t, {})
getmetatable(t).__index = nil
getmetatable(t).__newindex = nil
My suggestion to make delete and has (I still like exists) be a
primitive function that works on locals is a more disruptive change:
print(has(foo)) --> false
return foo --> error: Attempted access to undefined value 'foo'
>
> My own suggestion, totally ignored so far:
>
> Implement 'has' via a new metatable field, whose behaviour depends
> on its type.
>
> - nil or none: the current behaviour
> - nonnegative integer: value of #tbl, positive numeric keys being
> legal only if in the range 1..#tbl
> - table: a prototype containing legal keys
> - function: a decision procedure for establishing legality
>
I think it is an interesting approach that solves the original poster's problem.
It has merit. I prefer Eike's approach, but people have different tastes.
> -----------------------------------------------------------------------
>
> The next few points are comments rather than points already made.
>
> 1. Any solution that addresses only arrays does not solve the problem
> identified by the OP.
>
> 2. It's a pity there were not more posts along the lines of:
>
> - This is what we do in our organization.
> - This is how long we've been doing it.
> - This is how our programmers react to our way of doing it.
> - This is the way we implement it.
Personally, I run into this all of the time, but often outside of the
context of tables.
For example:
print(..., select(1, ...), select("#",...) ) --> nil nil 0
print(type(select(1,...))) -->error: bad argument #1 to 'type'
(value expected)
For this example, it seems silly, but in practice, it is not. Not
getting an argument and having it set to nil *are* really different
things. In the above example, Lua can't decide if select(1,...) is nil
or a non-value. I know why, but it isn't consistent and the details
are not easily accessible.
Does that work as an example?
--Andrew