Scoping of closure in a loop

44 views
Skip to first unread message

Stefano Cossu

unread,
Oct 28, 2025, 4:20:51 PM (9 days ago) Oct 28
to lu...@googlegroups.com
Hi there,
I entered this example code in the Lua interpreter:

> do
>> local function fn(s) print(i, ct, s) end
>> local a = {"a", "b", "c"}
>> local ct = #a
>> for i, v in ipairs(a) do fn(v) end
>> end
nil 3 a
nil 3 b
nil 3 c
>

Since I assumed that i and v are local to the ipairs loop, I would
expect the first printed value in each iteration to be the actual value
of `i` in the loop, because the `fn` closure would reach them as it
reaches `ct`. Why is that not so?

I am not sure exactly sure what the scope of i and v is. They are nil
outside the loop, so they are not global, and if they are local, why are
they not visible by the closure?

Thanks for any explanation.
OpenPGP_0x1716A1B35E826596.asc
OpenPGP_signature.asc

Luther Thompson

unread,
Oct 28, 2025, 5:21:08 PM (9 days ago) Oct 28
to 'Stefano Cossu' via lua-l

Upvalues are captured at the point where the function is defined, not where it's called. i and v are local to the for loop, so fn can't see them.

One thing I don't understand is how fn can see ct. When I run this code, I get:

nil     nil     a
nil     nil     b
nil     nil     c

The scope of a local variable does not start until its declaration, so within fn, both i and ct should be globals, and therefore nil.

Luther

Stefano

unread,
Oct 28, 2025, 5:49:26 PM (9 days ago) Oct 28
to lua-l
Thanks Luther, that's clear now. 

> One thing I don't understand is how fn can see ct

That's because while testing I had mistakenly declared ct as global previously, so it stuck in the interpreter. That added to my confusion. My mistake. 
s
Reply all
Reply to author
Forward
0 new messages