• Subject: Re: Lua5.0 new "For" question
• From: Björn De Meyer <bjorn.demeyer@...>
• Date: Sun, 22 Dec 2002 16:42:33 +0100

```Peter Hill wrote:
>
> I've been having a look through the Lua5.0(beta) documentation and noticed
> the new general "for" statement. What I want to know is why the "pair"
> function exists?
>
> Ie, why do we write:
>     a = {"alpha", "beta"}
>     for i,v = pair(a) do print(v) end
>
> Wouldn't it be just as fine to say:
>     a = {"alpha", "beta"}
>     for i,v = next,a do print(v) end
>
> The above should be just the same as as the internal assignments:
>     _f, _s, i, v = pair(a)
> and
>     _f, _s, i, v = next, a

First of all, you don't seem to know the correct syntax of the
for loop. In Lua 5, for a non-numerical foo, it's not "=" but "in".
You make this error consistently, so I assume you haven't even tried
to use Lua 5.

But you are right, the construct
for i,v in pairs(a) do end
is basically equivalent to
for i,v in next, a do end
I think pairs() is used for syntactic sugar, mostly.

>
> Which brings up a separate issue regarding the exp/exp1 situation. If I
> wanted to specify the initial index value in a "for" how would I? Surely:
>     for i,v = pair(a),123 do print(v) end
>
> would fail because, as a non-terminal in the assignment, "pair()" would be
> chopped down to a single return value, effectively becoming:
>     _f, _s, i, v = next, 123
>
> rather than the desired:
>     _f, _s, i, v = next, a, 123
>
> I'm sure some way of allowing non-terminal exp (vs exp1) has been mentioned
> before (no doubt ad-nausem) but in a case like this how does one get by
> without it?

In Lua 5, the "n-th" element of a table is only defined for numerical
indexes. In Lua, elements in tables are stored in indefinite order.
To do what you want to do, you can use ipairs() like this:

try = { [0] = "zero", [1] ="one", [2] ="two",
[3] ="three", [4] ="four", [5] ="five" };

for i, v in ipairs(try), try, 2 do print(i, v) end

Which outputs:
3       three
4       four
5       five

Note that the table try cannot represent a sparse array
because of the way ipairs() works. An improved version of
ipairs() could be written to handle that case.

> The generally solution would be to have some sort of return-value compiler
> directive. Eg, let's use "#" (being the "number" sign) which we define as:
>     n # f() -- truncate (or expand with "nil") to n values.
>     # f() -- use all return values
>     f() -- use one return value... same as 1#f()

Sorry, but I think this is so ugly it almost makes me weep.
Besides, you can already do what you want to do here in Lua 5,
like this:

function nres(n,
...)
local res = {};
if(n>arg.n) then n = arg.n; end;
-- Make sure n is not greater than the amount of arguments received.
for i = 1, n do res[i] = arg[i] end
-- Copy the first n arguments in a temporary table.
return unpack(res);
-- Unpack the table, so we only leave n arguments on the stack
end

You can test nres() with this function:

function makenres(n)
local res= {};
for i = 1, n do res[i] = "Value nr " .. i;
end;
return unpack(res);
end;

print(makenres(4)) gives as output:
Value nr 1      Value nr 2      Value nr 3      Value nr 4

And print(nres(2,makenres(5)) gives as output:
Value nr 1      Value nr 2

As can be seen from this example, the nres() function can
be used to trim the results of any function to the desired
amount of results.

> True, it's not compatible with the current method... but it's a lot clearer
> and fairly easy to adjust code to. Otoh, one could always add a global
> variable in Lua to specify which default one wants, eg "_TERMINAL_EXP =
> true".

Ugh! Sorry to say this, but I think you need to read the manual
more carefully. The problems you have can all be solved in
Lua 5.0, without having to change the language. You just
need to get aquiainted a bit more with the functional
programming  aspect and the flexibility of Lua. The changes
to the language you propose are unneeded, not to mention
very un-Lua like. I'm sorry if I sound stuck-up, but I
want to keep Lua pure and simple.

--
"No one knows true heroes, for they speak not of their greatness." --
Daniel Remar.
Björn De Meyer
bjorn.demeyer@pandora.be

```