lua-users home
lua-l archive

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



On 17/08/14 11:55 PM, Tim Hill wrote:
On Aug 17, 2014, at 7:10 PM, Coroutines <coroutines@gmail.com> wrote:
On an unrelated note: __pairs and __ipairs are not necessary to be
upstream -- I wish they were so it promotes an interface everyone
knows about, but you can just wrap ipairs() and pairs() of course.
I'm sad to see __ipairs go, I feel like we went back a step.

I’m really not sure where I stand on this whole ipairs() thing. The fact is, the various metamethods being added/extended are moving Lua more and more in the direction of generic programming, which is *probably* good as long as it doesn’t get out of hand (.Net or Java class libraries anyone? <shudders>).

So let’s say you wish to write a generic function that contains generic iteration. What does it look like? Well, you really have to supply two things: the item to iterate and the generator…

function generic_func_that_iterates_A(item, f)
	for k, v in f(item) do
		— stuff
	end
end

This is flexible if the same item may have multiple iterators, but in many cases it’s better if the item carries its own iterator. How does it do that? Using __pairs() of course…

function generic_function_that_iterates_B(item)
	for k,v in pairs(item) do
		— stuff
	end
end

To my mind, this is the real purpose of pairs(); to provide generic iteration for types with metatables. This is more elegant than passing a generator every time. Of course you can have the best of both A and B…

function generic_func_that_iterates_C(item, f)
	f = f or pairs
	for k, v in f(item) do
		— stuff
	end
end

But notice this is all about pairs(), not ipairs(). It’s pairs() and __pairs() that provide this generic model to my mind. ipairs() is really just a convenience function, created as an obvious companion to pairs(). After thinking it through I think Roberto and co are right; ipairs() is just a convenience for iterating over the numeric range [1,#t], and nothing else, and has no business having __ipairs() at all; the low-level __len/__index can do all the necessary abstraction.
Eh,

local i = 1
while t[i] ~= nil do
  local v = t[i]
  -- do some stuff here
  i = i+1
end

(Also faster than using ipairs())

—Tim