lua-users home
lua-l archive

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


Jasper:

On Sat, 9 Oct 2021 at 23:36, Jasper Klein <jasper@klein.re> wrote:
> The functions string.byte, string.sub, table.concat, table.move, etc. accept indices to the begin and end as parameters of a range in a table on which the function is applied. The end index is 'including' so this means its not possible to define a zero length range.
> When the begin index is passed the end index, it seems that the functions do nothing. So, there is no way to define a 'reversed' range.

I think that is how you define a zero length range. In ( my personal
favorite ) half-open interval way you use end=begin, in closed
intervals you just substract 1 from it, so end=begin-1, it seems to do
the trick.

> For someone that likes C++ as much as Lua, using indices as is common in the standard Lua functions, feels limiting compared to C++ iterators.
> With C++ iterators it is possible to define a zero length ranges and reversed ranges (with reverse iterators).

In the same way C++ indices is limited, but you can "easily" define
iterators. But, IMO,  they are not going to be easy or pretty in lua (
lack of generic loop and incrementing operators being some of the
reasons ). I mean, in C++ you can easily write

for (auto i = get_begin(), e=get_end() ; i!=e; ++i) {
dowhateverneedstobedonewith(*i); }

But in lua you do not have this king of ops, so I think you decay to
do
   local i = begin()
   local e= end()
   while(i!=e) do -- assumes metatable is right.
       do_whatever_with(i.get())
       i.advance() -- or increment or whatever.
   end

> The reason for bringing this up is that I'm writing a Lua module (in C++) to manipulate tables.
> I want to give the functions in this module an API with a standard Lua module 'look and feel' but also C++ iterator-like possibilities.
> At the moment I have two options:
> 1) Define a range by an index and a size. A reversed range has a negative size. 'end offset' instead of 'size' might be a better definition because negative sizes is a bit weird.
> This concept is not used by the standard Lua functions.

You can make range return a lua iterator, like ipairs or pairs. So you can do

t = {1,2,3,4,5,6}
for i, v in reverse_range(t, 2,4) do ... end -- ( i in case you need
to modify the table, or just return a setter if you feel fancy. )

> 2) Use begin and end indices as range definition as already used in Lua. Let the user handle the 'zero length' case.
> Allow the begin index to be passed the end index. In this case the sequence starts at the begin index and counts down until it has reached the end (including).

Given lua normally treats begin>end as empty I think autoreversing the
sequence would be confusing. IMO having, like C++, diferent range
creator would be much easier.

> * Which option do you like most for usage in an API?
> * What would you do to define a range in Lua?

In the table library I did, I use range() and similar functions, and I
have them ( with different names ) in lua ( closed ), half-open and
start-offset variants. It's just about a page of code ( for sequences
). You do not have that many types of range, and having different
functions make it easier for me than remembering magic things for
reversing.

Francisco Olarte.