lua-users home
lua-l archive

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


On Mon, 18 Aug 2014 08:35:23 -0500
Andrew Starks <andrew.starks@trms.com> wrote:

> On Monday, August 18, 2014, Jan Behrens <jbe-lua-l@public-software-group.org>
> wrote:
> 
> > On Mon, 18 Aug 2014 08:02:01 +0200
> > Dirk Laurie <dirk.laurie@gmail.com <javascript:;>> wrote:
> >
> > > I don't like it. I don't like Lua 5.3.0-alpha ipairs either.
> > >
> > > What you, and Lua 5.3.0-alpha, have been trying to do
> > > is to second-guess what semantics ipairs should have
> > > if a programmer has been tinkering with __len and __index.
> >
> > That is just one part of my proposal. I basically copied it from
> > Lua 5.3.0-alpha (incorporating Roberto's idea regarding the
> > conditional call of luaL_len).
> >
> > Please also consider the other aspect of my proposal to let
> > ipairs accept both functions and iterator triplets. This has
> > nothing to do with __len and __index.
> >
> > >
> > > And Lua 5.3.0-alpha is so prescriptive about it that the
> > > programmer does not even have the freedom to override
> > > that guess.
> >
> > I don't like either that Lua 5.3.0-alpha is not allowing any
> > customization here. I feel like a standard interface for
> > "ordinal iteration over whatever object" would really help a
> > lot of programmers. Removing __ipairs takes away this ability
> > (IMHO leading to chaos, as elaborated earlier).
> >
> > >
> > > I think _any_ iterator that is metatable-aware must either
> > > be very explicitly specified (e.g. by __pairs or __ipairs)
> > > or stashed in the table library, which can have its own tight
> > > well-specified protocol.
> >
> > Regarding tables, I would agree that it's a matter of taste
> > whether to interpret metamethods like __index and __len. I like
> > the interpretation Lua 5.3.0-alpha uses (disregarding the
> > previously discussed implementation issues).
> >
> > But my proposal is mainly not about the interpretation of that
> > metamethods. It also treats functions in a specific way, which is
> > rather type-dependent behavior than having to do anything with
> > metatables.
> >
> > If you consider my previously posted examples of supercool_ipairs
> > or the poweriterator C extension it also allows constructs like
> > this:
> >
> >
> > 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
> >
> > [...]
> >
> > All this got nothing to do with guessing what __index and __len mean.
> > It still works with the following simplified version of the extended
> > ipairs. The following code doesn't mention __index or __len:
> >
> > do
> >
> >   local function ipairsaux_raw(t, i)
> >     i = i + 1
> >     local v = rawget(t, i)
> >     if v then
> >       return i, v
> >     else
> >       return nil
> >     end
> >   end
> >
> >   local function ipairsaux_func(f, i)
> >     local v, v2, v3, v4, vn = f()
> >     -- variable arg number requires C implementation
> >     if v then
> >       return i + 1, v, v2, v3, v4, vn
> >     else
> >       return nil
> >     end
> >   end
> >
> >   local empty = {}
> >
> >   function ipairs(x, s, i)
> >     local mt = getmetatable(x) or empty
> >     local mt_ipairs = rawget(mt, "__ipairs")
> >     if mt_ipairs ~= nil then
> >       return mt_ipairs(x)
> >     elseif type(x) == "function" then
> >       if s == nil and i == nil then
> >         return ipairsaux_func, x, 0
> >       else
> >         local n = 0
> >         return function()  -- closure not avoidable here
> >           n = n + 1
> >           local v, v2, v3, v4, vn = x(s, i)
> >           -- variable arg number requires C implementation
> >           if v == nil then
> >             return nil
> >           else
> >             i = v
> >             return n, v, v2, v3, v4, vn
> >           end
> >         end
> >       end
> >     else
> >       return ipairsaux_raw, x, 0
> >     end
> >   end
> >
> > end
> >
> >
> > Regards
> > Jan
> >
> >
> 
> [...]
> 
> I think it is good to evaluate the need here. Is there really a big need to
> radically alter Lua and the way it does iterators?
> 
> -Andrew

I don't see where my proposal is "radically altering Lua". Where does
it "radically alter" Lua?

It's just:

* a small change in lbaselib.c that covers the behavior
  of ipairs when passing a function as first argument,

* keeping the __ipairs metamethod (which is no change at
  all compared to Lua 5.2).


> Is there really a big need

For the needs: See my previous posts (including the one regarding
different iterator invocations across different libraries).

But even if there was no urgent need at all, it would still allow for
new programming paradigms, while being only a minimal change to the
baselib (and no change to the language itself!).


Regards
Jan