inserting and removing is an O(1) for chained lists. Thats what a
sensible coder picks if he has a datastructure in which insert and
removes happen a lot. Or if the sorting is on the fly s/he picks a
tree so it becomes O(log(n)). Index operations on lists are expensive,
but they are still valid, so I would not forbit them. As I posted
before, if you look to some other high level languages, the beauty is
that you simply replace the basic data structure, which has exactly
the same interface, only the costs of operations differ.
> (II) Automatic Subtypes
What I've been pondering about in the lua hash+array way "the core
picks a data structure for you", is to enhance on this concept and
switch datastrucures on the fly. Like counting the index,
insert/remove operations and if it exceeds some level on the next
"rehash", dont rehash into a table but say into a chain. Additionally
some interface to give "hints" for the advanced coder could be done.
But maybe that idea is just too crazy.
> But I am not sure if that isn't almost always a
> sign for a bad implementation approach, whatever it is you are just
> implementing?
Indeed sometimes you have to do an insert once and index then a
thousend tims, so the array with insert/remove is perfect.
> Also, I'd opt for
> - throwing errors for stuff that is ambiguous, i.e. disallowed
> according to the above list;
> - keeping nils as they are, as non-first citizens but representation
> for 'not there/not used/deleted/free'.
All for it. I dislike the become a subtype by first use tough, since
that can as well be very confusing, especially if a vanilla table
might be "stamped" into this or that differently depending on which
subfunction it was first used. The precious newbie is easy going to
pull hair over that.
> (III) Implementation
>
> But it would appear more true to Lua to me, to assign metatables
> instead, to make the tables duck-type object specializations of type
> 'Set', 'Array' or 'List' to base type 'Table'. That need never be made
> explicit or stressing the notion of static types. The functions
> implemented could be the same for every subtype, only some throw
> errors instead of doing anything. And the act of tying the metatable
> in would be the specialization, that would happen on the fly, as soon
> as one decisive function is used on the table, as listed above.
>
> This would leave the problem of direct setting t[k]. That could also
> work via metatables, maybe something must be added to complement
> __newindex?
Likly, if used in large scale adding __read and __write is at more
efficient than proxy tables.
I thought about some intermediate hijacking, using the metatable
interface of the core, but
provide the user yet another metatable so s/he can make additional
logic to liking.
A idea I'm playing with is to add "__metatable" to metatable which is
returned when getmetatable(t) is called instead of the "true"
metatable. So in lua this could look like this:
t = {}
do
local proxymt = {}
local mt = { }
setmetatable(t, mt);
mt.__index = function(k)
if k < 0 then error("I dont want negative indici in there"); end
if proxymt.__index then proxymt.__index(k) end
end
mt.__setmetatable(p) = function(p) proxymt = p end
mt.__getmetatable(p) = function(p) return proxymt end
end
So the user could add transperently his logic for __index to it,
without affecting the demo logic here to not allow negative values.