lua-users home
lua-l archive

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


On Tue, May 25, 2010 10:41 pm, Edgar Toernig wrote:
> Mark Hamburg wrote:
>>
>> Since this discussion seems to be sparked by the deprecation
>> of ipairs, the other option to consider is whether there's a
>> way to make the value fetch more syntactically lightweight.
>
> Well, not that I would propose that for Lua 5.2 (it's a step
> backwards) but I have three variants of the for-statement ;-)
>
>   for k[,v] in t do ... end     -- pairs-like
>   for [i,]v over t do ... end   -- ipairs-like
>   for i=a,b[,c] do ... end      -- numeric

I think it's a good point that if for ... in ... do works in different
ways depending on the parameters, the opcodes for the loop structures
become more complicated if the types are determined at run time (as they
have to be). Adding more keywords (like above) doesn't sound very elegant
either, but it might make the code easier to compile and it also makes the
code easier to understand.

Mark Hamburg raised a good point about what loop code will look like after
ipairs is removed. It's one of my main concerns as well. I have quite a
few loops that look like this:

for i,v in ipairs(self.items) do
  doSomething(i, v)
end

The non-ipairs version has to introduce a new local variable in order to
be efficient:

local t = self.items
for i = 1, #t do
  local v = t[i]
  doSomething(i,v)
end

Another concern is that evaluating #t isn't always going to be a faster
operation, so you might end up traversing at least part of the table
twice, which could be bad for caches etc. If we eliminate #t, we end up
with:

local t = self.items
local i = 1
local v = t[1]
while v do
  doSomething(i,v)
  i = i+1
  v = t[i]
end

That's a lot of code for something that used to be really simple
syntactically. It also becomes quite obfuscated easily and we're now
introducing three local variables that exist outside the scope of the
actual loop and could interfere with visibility other variables introduced
before them.

Sure, I can implement ipairs in Lua, but that's probably taking a step
backwards in terms of efficiency. I think if ipairs is going away, the for
loop structure should be improved so that it can handle the job without
ipairs.

What if the for loop used a C function pointer stored as (or like) light
user data? When the for loop statement would be evaluated, the type of
loop would be determined based on the type of value immediately following
"in". The state information could be kept in a structure that is shared by
all three types of for ... in loops (possibly even the numeric for loop).
For each iteration, the function pointer is called by the opcode
performing the for loop. There's no self-modifying code involved, so it
seems reasonably elegant to me. Alternatively, the type of the first value
after "in" could be tested for each loop iteration (even though it can
never change, so it feels inefficient).

Juri Munkki
jmunkki@portalify.com