lua-users home
lua-l archive

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


Thank you all for your explanations, i understand i was misleading but it is more clear now.


De: "Javier Guerra Giraldez" <javier@guerrag.com>
À: "Lua mailing list" <lua-l@lists.lua.org>
Envoyé: Mercredi 13 Août 2014 17:45:19
Objet: Re: Iterator construction

On Wed, Aug 13, 2014 at 8:22 AM,  <astient@laposte.net> wrote:
> The 2 loops call the same function, but in the first case the local variable
> y is not retained (which is the normal behavior of local variable as i
> understand it), so the value of y stays at 1.

the first case:

         for i = 1,3 do
             iterator(table)()
         end

calls "iterator(table)" three times, and after each one, it calls the
returned function once.

in your iterator() function you define "local y=0", so the variable is
defined and assigned each time iterator() is called.  the inner
function sees that value but only once, since it's called only once
before iterator() is called again and redefines y.


> But in the second case, the variable y is retained by the "magic" of "in"
> command and thus can be iterated from 1 to 3, although it is the same
> function.


the "in" syntax isn't magic, just a little complex.  it evaluates the
_expression_ between the "in" and "do" keywords and expects to get up to
three values which are then used to manage the iteration.

in your second case:

          for i in iterator(table) do end

the _expression_ "iterator(table)" is called _once_ to initiate the
loop, and then it gets the inner function, two other values (nil in
this case) to drive the loop, so the inner function gets called
several times and it sees the increasing values of "y"

from the docs:

"""
A for statement like

     for var_1, ···, var_n in explist do block end
is equivalent to the code:

     do
       local f, s, var = explist
       while true do
         local var_1, ···, var_n = f(s, var)
         if var_1 == nil then break end
         var = var_1
         block
       end
     end
"""
(where f, s and var internal variables, invisible to Lua code)

so, your one-line loop is transformed into

     do
       local f, s, var = iterator(table)
       while true do
         local i = f(s, var)
         if i == nil then break end
         var = i
         -- empty block
       end
     end

you can see the only call to iterator() is outside the loop, but the
local pseudovariable f is set to your inner function and then it's
called several times.

--
Javier