lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


on 11/4/07 10:39 PM, Tom Barta at tbarta@gmail.com wrote:

> Unfortunately for many people, the "wrong" way to think about Lua is
> the way that nearly all mainstream languages work.  I'm curious if
> anyone has created a basic 'array' or 'vector' C module for Lua
> similar to how Python's numeric libraries work (array elements are a
> single contiguous type, rather than polymorphic objects).

It would help if the standard changed to have pairs and ipairs look for
__pairs and __ipairs metamethods. It's easy enough to change the
implementation of these routines, but providing extensions would be easier
if one didn't need to do this.

While doing this, I would be inclined to "deprecate" next to rawnext rather
than introducing a __next metamethod since use of such a metamethod is
largely likely to introduce performance problems.

That, however, probably necessitates adding a standard way to check for
empty tables other than next( t ) == nil and probably requires having this
look for an appropriate metamethod.

Or the standard definition of pairs could become (though it would need to be
written in C to really look into the metatables):

    local rawnext = next

    function pairs( t )
        local mt = getmetatable( t )
        if mt == nil then
            return rawnext, t, nil
        end
        local mt_pairs == mt.__pairs
        if mt_pairs ~= nil then
            return mt_pairs( t )
        end
        local mt_next = mt.__next
        return mt_next or rawnext, t, nil
    end

    function next( t, k )
        local mt = getmetatable( t )
        local mt_next = mt and mt.__next
        return ( mt_next or rawnext )( t, k )
    end

This way, pairs resolves the next function once so we don't have to do it
repeatedly. Still, this means that when overriding pairs, one probably also
has to override next for consistency. If instead one just recasts next as
rawnext, that issue largely goes away.

On a similar front, it would be good to provide similar overrides for all of
the array manipulation functions in table so that code can be written
without regard to whether one is working with tables or other objects.

Mark

P.S. An array object could be constructed as follows:

    userdata
        environment -> contents table
            -- a shared metatable with an __index function could
            -- handle subscript checking if desired
        metatable -> per object table
            __index = contents table
            manipulation functions standard
        userdata itself contains start and finish as desired

This uses one userdata and two tables per object. You can get by with a
shared metatable if you accept that indexing will be slower.

Special cases could then be constructed for things like arrays of numbers
though space efficient versions of these would suffer access penalties of
having to go through __index functions to get to the data.