[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