[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: ipairs in Lua 5.3.0-alpha
- From: Jan Behrens <jbe-lua-l@...>
- Date: Mon, 18 Aug 2014 16:35:08 +0200
On Mon, 18 Aug 2014 13:18:38 +0200
Jan Behrens <jbe-lua-l@public-software-group.org> wrote:
> Consider a function printcsv, which accepts a sequence:
>
> function printcsv(seq, sep)
> sep = sep or ","
> for i, v in ipairs(seq) do
> if i > 1 then io.stdout:write(sep) end
> io.stdout:write(tostring(v))
> end
> io.stdout:write("\n")
> end
>
> Calling this with a raw table is pretty much forward:
>
> printcsv{"a", "b", "c"}
> -- prints:
> -- a,b,c
>
> printcsv({"a", "b", "c"}, "; ")
> -- prints:
> -- a; b; c
This just got me to the idea that if ipairs is made to accept
functions (or even iterator triplets), we could also implement
a generic concat:
==================================================
function string.concat(sep, ...)
local t = {}
for i, v in ipairs(...) do
t[i] = tostring(v)
end
return table.concat(t, sep)
end
==================================================
Or optimized in C:
==================================================
int poweriterator_concat(lua_State *L) {
int sep = 0;
luaL_Buffer buf;
luaL_checkany(L, 2);
if (lua_isnoneornil(L, 1)) {
lua_pushliteral(L, "");
lua_replace(L, 1);
} else {
luaL_checkstring(L, 1);
}
lua_pushcfunction(L, poweriterator_ipairs);
lua_insert(L, 2);
lua_call(L, lua_gettop(L) - 2, 3);
lua_pushnil(L); // placeholder on stack at 5
luaL_buffinit(L, &buf);
while (1) {
lua_pushvalue(L, 2); // func
lua_pushvalue(L, 3); // state
lua_pushvalue(L, 4); // pos
lua_call(L, 2, 2);
if (lua_isnil(L, -2)) {
lua_pop(L, 2);
break;
}
lua_replace(L, 5);
lua_replace(L, 4);
if (sep) {
lua_pushvalue(L, 1);
luaL_addvalue(&buf);
} else {
sep = 1;
}
luaL_tolstring(L, 5, NULL);
luaL_addvalue(&buf);
}
luaL_pushresult(&buf);
return 1;
}
==================================================
This would give us much more power than table.concat:
(","):concat{"a", "b", "c"}
-- evaluates to: "a,b,c"
string.concat("; ", assert(io.open("testfile", "r")):lines())
-- evaluates to:
-- "This is line #1 of my testfile.; This is line #2 of my testfile."
string.concat(",", pairs{apple=true, pear=true})
-- evaluates to:
-- pear,apple
-- (ordering may vary)
I would find that really useful and pretty much straightforward.
I also don't see any negative side effects of making ipairs accept
functions or iterator triplets. Are there any?
I can understand that some of you don't miss generic iterators. But
they would allow for a new style of programming when using Lua.
As I said, I don't see any cons, only pros.
Can anyone come up with a real con?
Regards
Jan
- References:
- Speed of # operator (Was: ipairs in Lua 5.3.0-alpha), Dirk Laurie
- Re: ipairs in Lua 5.3.0-alpha, Roberto Ierusalimschy
- Re: ipairs in Lua 5.3.0-alpha, Jan Behrens
- Re: ipairs in Lua 5.3.0-alpha, Jan Behrens
- Re: ipairs in Lua 5.3.0-alpha, Roberto Ierusalimschy
- Re: ipairs in Lua 5.3.0-alpha, Jan Behrens
- Re: ipairs in Lua 5.3.0-alpha, Doug Currie
- Re: ipairs in Lua 5.3.0-alpha, Coda Highland
- Re: ipairs in Lua 5.3.0-alpha, Jan Behrens
- Re: ipairs in Lua 5.3.0-alpha, Andrew Starks
- Re: ipairs in Lua 5.3.0-alpha, Jan Behrens
- Re: ipairs in Lua 5.3.0-alpha, Jan Behrens
- Re: ipairs in Lua 5.3.0-alpha, Jan Behrens
- Re: ipairs in Lua 5.3.0-alpha, Dirk Laurie
- Re: ipairs in Lua 5.3.0-alpha, Jan Behrens