lua-users home
lua-l archive

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


You can generalize this for all iterators, and writing your own range iterator as you described, you can even apply it to the "numeric for". Syntactically, I'd consider a "range" iterator as Python has cleaner, but I do understand the performance concerns (mostly related to builtins being globals, globals being highly flexible, and thus Lua being unable to optimize such a thing to the fast numerical for in most cases). Sometimes I even question for-loops in general; function/callback-based iterators would work just as well, but hey, we're not going purely functional here. A decent compromise must be found. Such syntactical sugar is better implemented at a preprocessor level, or just as Lua. Possible Lua syntax for this:

-- Again iterator-based
for ... in iterator_else(function()
	-- this is your else-body
end, ipairs(table)) do

end

-- Functional, doesn't allow breaking unless you implement it as "return true" or the like;
-- might be more flexible as a different return value could be used for continuing. Comes at a performance penalty.
iterator_else(function(...)
	-- this is your loop body
end, function()
	-- this would be your else-body
end, ipairs(table)) -- iterator has to be at the end due to varargs;
-- if you restrict your iterators, you may move this to the beginning of the parameter list

-- Or yet another one, an iterating func that returns whether the loop body was ran:
if iterator_else(function(...)
	-- loop body
end, ipairs(table)) then
	-- this is your else
end

Even more syntax is possible when you start using debug.setmetatable, overriding operators, but that gets rather hacky.

On 17.03.22 09:06, Benoit Germain wrote:
I didn't say it can't already be done. However, what if I want to iterate over something more complex than a table+pairs dataset? The generic for loop is much more powerful than that:
stat ::= for namelist in explist do block end
Any flavor of namelist/explist would require a "specialized generalization" similar to what is described in chapter 3.3.5 of the documentation, to extract the iterator function, for each length of namelist. This would defeat what I am after: a simple way of expressing my intent. I am not saying it's important, just that it would help write expressive code in that kind of situation without having to jump through hoops. After all, we have the numerical for loop in the language:
stat ::= for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end
Is it important? Maybe not because Lua could offer a range function to perform numerical loops like so, just like it offers pairs()/next() to iterate over table contents:

for i in range(from,to,step) do
    print(i)
end

However the numerical loop exists. (And yes, I understand that I am the devil's advocate here, as the numerical loop saves function calls, so it is beneficial for performance reasons).

Anyway, no big deal. Either Lua authors think it's worthwhile, or not. The most likely is that they already had that idea on their own and decided against it, for reasons of minimalism: don't do it if it's not needed, just like you said. Time to stop the noise :-).


--
Benoit.