lua-users home
lua-l archive

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




On Thu, May 21, 2020 at 1:43 PM Andrew Gierth <andrew@tao11.riddles.org.uk> wrote:
>>>>> "Coda" == Coda Highland <chighland@gmail.com> writes:

 Coda> Because there's no need for a metamethod for something as simple
 Coda> as ipairs()

 >> Some of us greatly disagree with this position - in particular, it
 >> seriously impacts what you can do with userdatas.
 >>
 >> For example, if embedding into an environment (e.g. a database) which
 >> has a native array type (such as SQL arrays) which can be iterated
 >> sequentially more efficiently than they can be indexed into (because
 >> they have variable-length elements), it means that you can't just
 >> provide an __ipairs and have everything just work in the obvious way;
 >> instead, ipairs() will work inefficiently and you have to provide a new
 >> but functionally identical method.

 Coda> IIRC the whole reason that ipairs doesn't need a dedicated
 Coda> metamethod is because there's ALREADY a metamethod for it: __len.
 Coda> If "for i = 1, #ud" works then "for k, v in ipairs(ud)" ought to
 Coda> work, I thought.

That doesn't address the issue I raised above at all.

An __ipairs metamethod dedicated to a specific userdata type has the
option of storing the "current index" in some fashion that respects the
underlying data structure. In 5.4 this doesn't work, and so when the
user does  "for k,v in ipairs(ud) ..."  then the userdata just sees an
unrelated series of calls to __index(ud,1), __index(ud,2), ... etc.

--
Andrew.

As I mentioned in one of my follow-up messages, I figured that out.

But I think that letting the userdata figure out those unrelated calls is actually better overall -- after all, wouldn't you want "for i = 1, #ud" to get the fast path? Wouldn't you want "a, b, c = ud[0], ud[1], ud[2]" to get the fast path?

It doesn't sound TOO unreasonable to implicitly assume iteration on the backend until you break sequence. It's a bit harder to implement but it would be better overall.

/s/ Adam