lua-users home
lua-l archive

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


It would be nice to be able to use functions returning multiple values
in table constructors.
Something like {color(1,2,3),'etc'} producing {{"r",1},{"g",2},{"b",3},'etc'}
Workarounds have been proposed before:
http://lua-users.org/lists/lua-l/2004-08/msg00333.html
http://lua-users.org/lists/lua-l/2001-06/msg00172.html
But it seems (at least to me) that they somewhat mess up the clarity
of the declaration and that clarity is kind of the whole point when
used for declarative programming.
Declarations parsed by lpeg or other heavyweight solutions would solve
the problem and could be 'as expressive and clean as possible', but
I'd like to avoid that.

I had the idea that functions could return a single table holding the
return values and then the code using the declaration could use a
custom iterator that would ignore the wrapping table. This has the
advantage that the code using the declaration can be 'as is' (just
changing ipairs to iwpairs) and the table constructor can look like
{color(1,2,3),'etc'} and the result can iterate as
{{"r",1},{"g",2},{"b",3},'etc'}
here is a first attempt at the iterator:

-- iterator that enters and ignores tables containing 'isWrap'
-- i.e  {{isWrap=true,'A'},'B'} will iterate as {'A','B'}
-- and  {{isWrap=true,{isWrap=true,'A','B'},'C'},'D'} will iterate as
{'A','B','C','D'}
function iwpairs(tbl)
	return function(ts,si)
		local function f(ts,si)
			local s = ts[si]
			if not s then return end
			s.i = s.i + 1
			local v = s.t[s.i]
			if not v then return f(ts,si-1) end
			if type(v)=="table" and v.isWrap then
				ts[#ts+1] = {t=v,i=0}
				return f(ts,si+1)
			end
			return si,v
		end
		return f(ts,si)
	end, {{t=tbl,i=0}}, 1
end

Any suggestions on different idoms or whatever?
I'm looking forward to the gems book - perhaps "Table binding, and the
joy of declarative programming" will help.
Is it possible lua will allow multiple rv's in tbl constructors in the future?
- Carl