lua-users home
lua-l archive

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


RLake:
> Wim is quite right: I blew it. His works and mine doesn't.
>
> However, I don't think that voids the issue about "next is a more basic
> operation than pairs". Of course, it is. The issue is that it is difficult
> to write a general "next" routine which doesn't retain state.

The difficulty of writting a "__next" routine is basically on a case-by-case
basis depending on the implementation of the __index meta function.
Sometimes it might turn out inefficient... though in the "__index as a
Table" case it performs reasonably well (being on the same Order as a normal
key lookup for such a table).


> Peter: your effort is well-done, but I think even after doing it you would
> admit that Wim's solution is shorter and faster, and easier to write.

True. But whether it is useful or not depends on usage, and _that_ is up to
the programmer. If the programmer wants to mimic a table (using metamethods
on tables or user data) then they will NEED a way to intercept both "next()"
and "lua_next()".

If "__next" is too inefficent to implement for a particular table design
then the programmer _might_  instead choose to intercept "pairs()". However,
since I don't think  there is a "lua_pairs()" function (though I might be
wrong), one should be able to just reimplement "pairs()" as one wishes.


> I am not saying that "next" is not a fundamental operation: just that next
> factories are often easier to come up with than static nexts. :)

Agreed. However I think there is a place for both.

If the object you are dealing with is mimicking the behaviour of a table
(ie, a fast-keyed object) then it *should* also be able to respond correctly
to 'next()' AND 'lua_next()' to sustain the paradigm. The authors have
chosen to do implement the iteration of TABLES using a repeated keyed lookup
and, to respect that choice, we need a __next metamethod added.

That said, in common usage people may prefer to produce more general
generator functions that run on internal state (especially when they do not
actually match table behaviour). It might be nice, therefore, if the 'for'
statement could also support that format (ie, a single function closure
which is repetively called until nil is returned). Eg:

  -- Example generator.
  function roll_dice(n)
    local i = 0
    return
      function()
        if (i<n) then
          i = i +1
          return math.random(6)
        else
          return nil
        end
      end
  end

  for v in roll_dice(5) do write('  '..v) end

which would display something like
  4  6  1  3  4

*cheers*
Peter Hill.