lua-users home
lua-l archive

Re: ipairs in Lua 5.3.0-alpha

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


On 2014年8月13日 22:33:23 +0200
Jan Behrens <jbe-lua-l@public-software-group.org> wrote:
> By principle, however, it is not possible to reduce this overhead,
> because the way the for-loop works in Lua, we may only pass one Lua
> value (the second value of the triplet) as state. Unless luaB_ipairs
> creates either a closure or a table that contains the length
> information (and thus the termination point of the iteration), we
> cannot remember the length and will have to redetermine it during every
> iteration step. Creating tables or closures, however, would have an
> even greater perfomance impact.
On 2014年8月15日 03:07:16 +0200
Jan Behrens <jbe-lua-l@public-software-group.org> wrote:
> Sorry to bring this up... but... consequently, maybe the global ipairs
> function should be completely removed and replaced by a language
> construct in the long term?
> 
> Consider:
> 
> for v = t[i] do
> print(i, v)
> end
I just came up with a better idea, which only introduces minimal
changes into the language, but allows a removal of the __ipairs
metamethod, yet avoiding re-evaluating the length for every
iteration step: adjusting Lua's for-statement in such way that more
than one state variable can be passed.
This - at first - looks like it would break downward compatibility.
But it does not.
Lua 5.3.0-alpha works like this:
============================================================
function lua53alpha_for(args)
 local f, s, var = table.unpack(args.explist)
 local block = args.block
 while true do
 local results = {f(s, var)}
 if results[1] == nil then break end
 var = results[1]
 block(table.unpack(results))
 end
end
do
 local function lua53alpha_ipairs_aux(t, i)
 print("Evaluating length here!")
 if i < #t then
 i = i + 1
 return i, t[i]
 else
 return nil
 end
 end
 function lua53alpha_ipairs(t)
 return lua53alpha_ipairs_aux, t, 0
 end
end
t = {"a", "b", "c"}
lua53alpha_for{explist = {lua53alpha_ipairs(t)}, block = function(i, v)
 print(i, v)
end}
-- results in:
-- Evaluating length here!
-- 1 a
-- Evaluating length here!
-- 2 b
-- Evaluating length here!
-- 3 c
-- Evaluating length here!
============================================================
NOTE: Of course, Lua internally doesn't create tables here. I just need
 to create tables in the above example code to demonstrate the way
 Lua works. It should be understood as pseudocode.
Because Lua 5.3.0-alpha can only deal with one state variable, it needs
to re-evaluate the length in the "lua53alpha_ipairs_aux" function
(calling "luaL_len" in "ipairsaux" in baselib.c).
But why don't we allow more than one state variable?
Consider the following (pseudo)code:
============================================================
function alternate_for(args)
 local f = args.explist[1]
 local statecount = math.max(1, #args.explist - 2)
 local s1_s2_sn_var = {}
 local block = args.block
 for i = 1, statecount+1 do
 s1_s2_sn_var[i] = args.explist[i+1]
 end
 while true do
 local results = {f(table.unpack(s1_s2_sn_var))}
 if results[1] == nil then break end
 s1_s2_sn_var[statecount+1] = results[1]
 block(table.unpack(results))
 end
end
do
 local function alternate_ipairs_aux(t, maxn, i)
 if i < maxn then
 i = i + 1
 return i, t[i]
 else
 return nil
 end
 end
 function alternate_ipairs(t)
 print("Evaluating length here!")
 return alternate_ipairs_aux, t, #t, 0 -- not a triplet but a quadruple
 end
end
t = {"a", "b", "c"}
alternate_for{explist = {alternate_ipairs(t)}, block = function(i, v)
 print(i, v)
end}
-- results in:
-- Evaluating length here!
-- 1 a
-- 2 b
-- 3 c
-- alternate_for is backwards compatible to lua53alpha_for:
alternate_for{explist = {lua53alpha_ipairs(t)}, block = function(i, v)
 print(i, v)
end}
-- results in:
-- Evaluating length here!
-- 1 a
-- Evaluating length here!
-- 2 b
-- Evaluating length here!
-- 3 c
-- Evaluating length here!
============================================================
I'd like to know if this is feasible for Lua 5.3.
Regards
Jan Behrens

AltStyle によって変換されたページ (->オリジナル) /