lua-users home
lua-l archive

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



This is almost there..

Now IF we only can get the '__len' metamethod to be applied to tables (as it should, in my opinion...).   That would allow wrapping the tuples into table-looking proxy, with #t and t[k] working as usual.

Current definition:

 function len_event (op)
       if type(op) == "string" then
         return strlen(op)         -- primitive string length
       elseif type(op) == "table" then
         return #op                -- primitive table length
       else
         local h = metatable(op).__len
         if h then
           -- call the handler with the operand
           return h(op)
         else  -- no handler available: default behavior
           error(···)
         end
       end
     end

Suggestion:

 function len_event (op)
       if type(op) == "string" then
         return strlen(op)         -- primitive string length
       else
         local h = metatable(op).__len
         if h then
           -- call the handler with the operand
           return h(op)
         elseif type(op) == "table" then
           return #op                -- primitive table length
         else  -- no handler available: default behavior
           error(···)
         end
       end
     end

I fail to see a downside on this; it would only 'hurt' people using the '#' operator (an added check for the metamethod even if it's not there), and that exact case seems to be what this whole message thread is about: '#' not being good with holes, and tails.

It would also allow people to rewrite '__len' to be always safe, if they choose to.  They could only do this for tables they KNOW would be carrying holes, so no extra burden would be implied on the rest of Lua.

Small change, can we have that and Shut Up?  :!

-asko


PA kirjoitti 4.8.2007 kello 16:29:


On Aug 04, 2007, at 11:23, Duck wrote:

So don't have holes in arrays :-)

Well... varargs routinely have nil values in them.... don't use varargs then?!? At that rate, not much will be left of Lua. Plus, there is no compelling reason for such a small, tight language to be littered with body-traps, isn't it?

In any case, here is a revisited 'tuple' implementation of sort:

Tuple = function( ... )
    local aList = { n = select( '#', ... ), ... }

    return function( aKey, anIndex )
        local anIndex = aKey or ( ( anIndex or 0 ) + 1 )
        local aValue = aList[ anIndex ]

        if aKey == '#' then
            return aList.n
        elseif aKey == '*' then
            return unpack( aList, 1, aList.n )
        elseif aKey then
            return aValue
        elseif anIndex <= aList.n then
            return anIndex, aValue
        end
    end
end

Usage example:

local aTuple = Tuple( nil, 'a', nil, 'b', nil, 'c', nil )

print( aTuple( '#' ) ) -- count
print( aTuple( '*' ) ) -- all values
print( aTuple( 2 ) ) -- one value

for anIndex, aValue in aTuple do -- enumerate
    print( anIndex, aValue )
end

> 7
> nil     a       nil     b       nil     c       nil
> a
> 1       nil
> 2       a
> 3       nil
> 4       b
> 5       nil
> 6       c
> 7       nil