[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: A rant about Lua
- From: "David Manura" <dm.lua@...>
- Date: Wed, 31 Dec 2008 22:56:04 -0500
On Wed, Dec 31, 2008 at 5:17 PM, Benjamin Tolputt wrote:
> On 12/31/08, Lee Hickey wrote:
>> http://julien.danjou.info/blog/index.php/post/2008/12/30/Rants-about-Lua
> I don't understand why the '#' syntax does not use the __len metamethod
See http://lua-users.org/wiki/LuaFiveTwo concerning __len, __pairs,
and __ipairs.
Note that in contrast to the proposed __len metamethod for tables, the
proposed __pairs/__ipairs metamethods are not integral to the Lua VM.
They are used only conventionally by the pairs/ipairs iterator
functions. You can alternately use your own iterator functions, even
ones that honor __pairs/__ipairs, or redefine pairs/ipairs from Lua.
I'm not certain if next and lua_next are in any way affected though in
5.2 (perhaps not).
>From the blog:
> The problem is that standard functions like table.insert or
> table.remove do raw accesses to the table.
True, the table.* functions use raw gets/sets. I think these would be
better named array.* since they are mostly, though not exclusively,
designed for "raw arrays"--i.e. tables containing positive integer
keys and lacking overridden operators defined in a metatable. This is
in contrast to metatable-backed tables or userdata used to represent
interfaces to abstract data types with overridden operators. A
typical example of raw arrays is for efficient /internal/
implementations--an algorithm inside a function or internal storage
for a data type.
Therefore, I question why table.* functions should honor metamethods.
If you want your ADT to have an "insert" operation, you could
implement it as a dynamically bound method:
obj:insert(pos, value)
For a raw array, you can do setmetatable({}, {__index=table}) to allow
consistent calling. However, that calling convention is not supported
for raw arrays lacking a metatable and not containing 'insert' as a
raw key--hence, the various table.* functions as non-members.
Another solution is to implement your own set of table.* like
functions that honor some more fundamental array-like ADT interface:
myarray.insert(obj, pos, value)
-- only calls public methods (including [] operator) on obj
For debugging it may even be useful to redefine table = myarray.
Along similar lines, the string.* functions only operate on raw Lua
strings. You cannot define your own custom string type (using tables
or userdata) and pass it to the string.* functions. You could,
however, in the same manner, use dynamic binding (e.g. s:find(...)) or
reimplement your own string.* functions to operate on a more abstract
string interface (see http://lua-users.org/wiki/StringLibraryInLua ).
We have a similar situation for io.* functions. (Related discussion:
http://lua-users.org/wiki/LuaVirtualization .)