lua-users home
lua-l archive

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


It was thus said that the Great Andrew Starks once stated:
> On Wed, Dec 10, 2014 at 8:52 AM, Dirk Laurie <dirk.laurie@gmail.com> wrote:
> > 2014-12-10 16:44 GMT+02:00 Rena <hyperhacker@gmail.com>:
> >
> >> Interesting. Why is __tostring not a core metamethod? The distinction
> >> seems arbitrary to me.
> >
> > A core metamethod is a fallback. It is called when Lua does not
> > know what to do, as a last resort instead of throwing an error.
> > __tostring, __pairs etc are called _instead_ of what Lua knows
> > to do.
> >
> 
> I don't make that distinction, even when I'm reminded that the authors do.
> 
> The reason is that, to me, it's meaningless. It works or it does not
> work and remembering where it works and doesn't is not something that
> I care to invest the time to memorize. At best, I know that whenever I
> define `__ipairs`... sort of worry that it may not work, if my table
> is handed to a library that may not honor it. To my way of thinking,
> there are fields that are attached to metatables that begin with `__`
> and end with the name of the method that they modify. Anything beyond
> this, to paraphrase the Bible, is complex.
> 
> I don't know if this is important enough to bring up in another
> thread, but I also don't like the deprecation of `__ipairs`. Whatever
> the redundancy it may suffer, it is clear to the writer or reader of
> the code that a sequence of key/value pairs, iterated in a consistent
> order, is expected. If `ipairs` and `pairs` exist and we allow for a
> way to override `pairs`, then consistency would require a
> corresponding way to override ipairs.

  To recap:  in Lua 5.2, ipairs() will attempt to call __ipairs(), which
should return an iterator function, self and an initial value; otherwise,
ipairs() supplies the iterator function, self and an initial value.

  The default iterator function goes from index 1 until self[index] returns
nil.  I suspect that most (if not all) iterator functions returned from
__ipairs() will do the exact same thing, although it doesn't have to be:

	mt =                                 
	{
	  __ipairs = function(t) 
	    local function iter(s,k)
	      if k == -1 then
	        return 'one',"ONE"
	      elseif k == 'one' then
	        return 'two',"TWO"
	      elseif k == 'two' then
	        return 'three',"THREE"
	      else
	        return nil
	      end      
	    end
	
	    return iter,t,-1   
	  end  
	}

	x = setmetatable({},mt)

	for index,value in ipairs(x) do
	  print(index,value)
	end

	one	ONE
	two	TWO
	three	THREE

  At this point, you could use __pairs().  Okay, ipairs() could then check
to see if the initial value returned from __ipairs() is '0' (the default
value if __pairs() doesn't exist) but then, why even bother with __ipairs()? 
I suppose it *could* check for an integer initial value, but then, is it
then a sequence as Lua even defines it?  Is that an issue? Consistent even?

  I know, there's signalling intent.  But the default iterator from ipairs()
supports __index, and in Lua, a sequence for ipairs() is defined as a
sequence of integer keys from 1 to n with non-nil values.  [1]

> I may be misunderstanding this issue and I may be mistaken about 5.3
> deprecating it. If I am correct, then it appears to me that the
> evolution of Lua is such that  eradicating redundancy is valued over
> consistency. "Consistency" can be argued about (see math library
> change).

  If that were true, then ipairs() would be removed as you can always do:

	for i = 1 , #t do ... end

  -spc (Viewing this from a userdata perspective ... )

[1]	I would really expect Thiago, Rena and Coroutines [2] to be upset
	over the removal of __ipairs() as (to me) they seem like the type of
	people that love overriding how the language works.

[2]	What ever happened to Coroutines anyway?