lua-users home
lua-l archive

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


On Wed, Jun 10, 2009 at 1:10 PM, John Hind<john.hind@zen.co.uk> wrote:
> Could I push my luck by asking if there is a position on '__iter'? I really
> cannot see any downsides of this (except of course for the usual concerns
> about any change) and it does seem to offer an 'easy gain' in terms of
> end-user simplification.

Lua 5.0 had a TFORPREP opcode, which was inserted in the bytecode
stream prior to a generic for loop. It would effectively replace "t"
with "next, t" for generic for loops over tables. This opcode was
marked as "for compatibility only" in the 5.0 sources, and is
completely removed in 5.1, so adding something similar back in for 5.2
would seem unlikely.

The 5.1 documentation lists the following as psuedo-code for a generic for loop:
do
  local f, s, var = explist
  while true do
    local var_1, ···, var_n = f(s, var)
    var = var_1
    if var == nil then break end
    block
  end
end

The 5.0 behaviour was something more akin to:
do
  local f, s, var = explist
  if type(f) == "table" then f, s = _G.next, f end
  while true do
    local var_1, ···, var_n = f(s, var)
    var = var_1
    if var == nil then break end
    block
  end
end

Your proposed behaviour would be similar to:
do
  local f, s, var = explist
  local mt = getmetatable(f)
  if mt and mt.__iter then f, s, var = mt.__iter(f) end
  while true do
    local var_1, ···, var_n = f(s, var)
    var = var_1
    if var == nil then break end
    block
  end
end

To some people, the 5.0 behaviour and proposed behaviour make a for
loop less readable rather than more readable. With the 5.1 behaviour,
it is simple to see what the iterator function, iterator state and
initial variable will be when reading a for loop. With other
behaviour, you cannot tell what they will be, as what looks like the
iterator function may turn out to be an object with an __iter
metamethod which supplies the iterator function, iterator state and
initial variable.

>From a performance point of view, the proposed behaviour would add an
extra bytecode instruction to each generic for loop, even for those
which don't go on to use __iter. It also adds another opcode to the
VM's central switch statement, and a small central switch statement is
a nice thing.