In addition, (3) would also allow to only allocate the actual required
amount of memory for the array instead of, worst case, use almost
twice of that.
Doubling the size keeps the amount of work required to append an element to the array part of a table from becoming quadratic. Appending an element takes O(1) works amortized.
Creating a set of routines that implement the semantics suggested is not that hard. There are many ways to do it. A suggestion: store the length of an 'array' in a table using weak keys:
local array_length = setmetatable({}, {
__mode = 'k',
__index = function(t, a)
return error("table not found in array_length")
end,
})
Creating an 'array':
local array_mt = {
__len = function(t) return array_length[t] end,
}
function new_array(n, ...)
local a = setmetatable({...}, array_mt)
array_length[a] = n
return a
end
A replacement for the iterator:
local function apairs(a)
local n = #a
local i = 0
return function()
if i < n then
i = i + 1
return i, a[i]
end
return nil
end
end
Do we really need to expand the language?