Lua Virtualization

lua-users home
wiki

Difference (from revision 9 to current revision) (minor diff)

Changed: 1c1
This page holds some information and discussion that might be useful to those interested in using Lua as a language that is fully virtualizable.
In the Lua language, values are only partly "virtualizable". Here, virtualizable means that any object with a metatable (table or userdata) can act as if it were a value of any other type, including the built-in types.

Changed: 3,5c3
Here, virtualizable means that any object with a metatable (table or userdata) can act as if it were a value of any other type, including the built-in types.

Following is a summary of how close the latest release of Lua (5.0.2) is to supporting this:
Following is a summary of how close Lua (5.1) is to being virtualizable:

Changed: 12,13c10,11
Equality a == b Limited* __eq
Ordering a < b Limited* __lt, __le
Equality a == b Limited[*] __eq
Ordering a < b Limited[*] __lt, __le

Changed: 17c15
Negation not a No
Boolean Logic not a, a and b No

Changed: 21,22c19,20
Get length string.len(a) No
Other utility string.find, etc. No
Get length string.len(a) No[!]
Other utility string.find, etc. No[!]

Changed: 27,28c25,28
Iterating for x in pairs(a) No
for x in ipairs(a) No Fix is trivial with small overhead
Length #a Mostly __len (but requires userdata before 5.2)
Iterating for x in pairs(a) No Fix is trivial [#]
raw operations rawget(a,k) No
array functions table.insert(a,b) No

Changed: 31c31
Invoking a(x, y) Yes __call +
Invoking a(x, y) Yes __call [+]

Changed: 34c34,36
Resuming coroutine.resume(a) No
Resuming coroutine.resume(a) No[!]

File handles io.type(a), ... No[!] See also I/O library abstraction [@]

Added: 37a40
type function type(a) No

Changed: 40c43,47
* Limited: Lua defines an equality or inequality among different types to always yield false.
[*] Lua defines an equality or inequality among different types to always yield false. The __eq metamethod also always returns true for values that are raw equal, but this doesn't support the behavior of the value NaN=0/0, where typically NaN ~= NaN.

[+] There are a couple of places in Lua where the __call metamethod is not checked. One of these is the __index metamethod itself (this affects FuncTables).

[!] Native types can have metatables, allowing you to using : notation (eg. aString:find(aPattern)), which is virtualizable. Only some types like strings have the metatable defined by default, but it can be added via debug.setmetatable.

Changed: 42c49,51
+ There are a couple of places in Lua where the __call metamethod is not checked. One of these is the __index metamethod itself (this affects FuncTables).
[#] See GeneralizedPairsAndIpairs for virtualizing pairs/ipairs/next. Also see LuaFiveTwo.

[@] LuaList:2008-07/msg00345.html, LuaList:2005-05/msg00178.html

Changed: 55,59c64
I made a couple of changes to the chart, I hope whoever created this page doesn't mind. Also, I put code at GeneralizedPairsAndIpairs which "virtualizes" (if you like) pairs and ipairs; it relies on some 5.1 API calls but could be easily modified for 5.0.2.

Some (but not all) of the holes are filled-in in Lua 5.1. In particular, each native type has a metatable, allowing you to write string functions in : notation (eg. aString:find(aPattern)), which I think deals with all of the package.method issues in the chart. (The math library is not introduced into the Number metatable as of 5.1work6, but it is trivial to do.)

Note: In the case of a .. b where one of a and b is a number and the other one is an object with a __concat metamethod, the number will be converted to a string before the metamethod is called. Also, .. is right-associative, but a has priority if both a and b have __concat metamethods. So presented with a .. b .. c, where all three have metamethods, the sequence will be: ameta.__concat(a, bmeta.__concat(b, c)). Furthermore, in the case of a .. 34 .. 56 the result will be ameta.__concat(a, "3456"). Some of these might be surprising.
Note: In the case of a .. b where one of a and b is a number and the other one is an object with a __concat metamethod, the number will be converted to a string before the metamethod is called. Also, .. is right-associative, but a has priority if both a and b have __concat metamethods. So presented with a .. b .. c, where all three have metamethods, the sequence will be: ameta.__concat(a, bmeta.__concat(b, c)). Furthermore, in the case of a .. 34 .. 56 the result will be ameta.__concat(a, "3456"). Some of these might be surprising.

In the Lua language, values are only partly "virtualizable". Here, virtualizable means that any object with a metatable (table or userdata) can act as if it were a value of any other type, including the built-in types.

Following is a summary of how close Lua (5.1) is to being virtualizable:

   Operation           Example             Works?     Metamethods/comments
   ---------           -------             ------     --------------------
Numbers
   Arithmetic          a + b               Yes        __add, __sub, __mul, __div, __pow, __unm
   Equality            a == b              Limited[*] __eq
   Ordering            a < b               Limited[*] __lt, __le

Booleans
   Truth value         if a then           No         Would add overhead to the idiom 'if table[key] then'
   Boolean Logic       not a, a and b      No

Strings
   Concatenation       a .. b              Yes        __concat  (see below)
   Get length          string.len(a)       No[!]
   Other utility       string.find, etc.   No[!]

Tables
   Indexing            a[b]                Yes        __index
   Write to index      a[b] = c            Yes        __newindex
   Length              #a                  Mostly     __len (but requires userdata before 5.2)
   Iterating           for x in pairs(a)   No         Fix is trivial [#]
   raw operations      rawget(a,k)         No
   array functions     table.insert(a,b)   No

Functions
   Invoking            a(x, y)             Yes        __call [+]
   
Threads
   Resuming            coroutine.resume(a) No[!]

File handles           io.type(a), ...     No[!]      See also I/O library abstraction [@]

Misc
   String repr.        tostring(a)         Limited    __tostring (not honored by C lua_tostring)
   type function       type(a)             No

[*] Lua defines an equality or inequality among different types to always yield false. The __eq metamethod also always returns true for values that are raw equal, but this doesn't support the behavior of the value NaN=0/0, where typically NaN ~= NaN.

[+] There are a couple of places in Lua where the __call metamethod is not checked. One of these is the __index metamethod itself (this affects FuncTables).

[!] Native types can have metatables, allowing you to using : notation (eg. aString:find(aPattern)), which is virtualizable. Only some types like strings have the metatable defined by default, but it can be added via debug.setmetatable.

[#] See GeneralizedPairsAndIpairs for virtualizing pairs/ipairs/next. Also see LuaFiveTwo.

[@] LuaList:2008-07/msg00345.html, LuaList:2005-05/msg00178.html

Advantages of virtualization:

Disadvantages:

RiciLake adds:

Note: In the case of a .. b where one of a and b is a number and the other one is an object with a __concat metamethod, the number will be converted to a string before the metamethod is called. Also, .. is right-associative, but a has priority if both a and b have __concat metamethods. So presented with a .. b .. c, where all three have metamethods, the sequence will be: ameta.__concat(a, bmeta.__concat(b, c)). Furthermore, in the case of a .. 34 .. 56 the result will be ameta.__concat(a, "3456"). Some of these might be surprising.

RecentChanges · preferences
edit · history
Last edited September 25, 2010 3:10 am GMT (diff)