lua-users home
lua-l archive

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


Moving functions out of a loop is not as simple as you think: the loop may not be visible at all and come from an invisible outer scope. The new function declaration will be made incide a deep call.
If then that function declaration automatically inherits many upvalues that are useless, there will always be a new function created at each call. And this makes no sense.
Eliminating all useless upvalues (even if they are in lexical scope) from the set of upvalues is then necessary: if at least this set of upvalues is now empty, it makes no sense at all to create a new closure at each call: a static closure should then be generated always by the compiler, without even having to lookup in a cache if there are other closures with the same set of upvalues (with the same effective reference to the same variable from the same outer scope).

Note also that if there are remaining upvalues in that set, the effective value of these variables is still mutable: nothing warranties it will be immutable, so the upvalues are normally variable references, not "constants", except if they are declared this way or by a deep inspection of varaible mutation within the lexical scope.

So I still maintain this is a bug for the exposed case: the set of upvalues is empty, the closure should then be static, and it does not need at all any cache.


Le ven. 9 août 2019 à 19:30, Javier Guerra Giraldez <javier@guerrag.com> a écrit :
On Fri, 9 Aug 2019 at 10:15, Dennis Fischer <darkwiiplayer@hotmail.com> wrote:
> To me it's the behavior of versions 5.2 and 5.3 that seems like a bug.

in 5.1 and before, any function declaration returns in a new function
object.  so they "feel" a bit like tables, where every "{}" creates a
new, different table.

in 5.2/3, if two functions are really identical, they're one and the
same.  so they "feel" a bit like strings, where two identical strings
are the same one (ignoring "large strings" (de)optimizations).

Of course, tables are mutable, so returning an old one would be total
chaos, while strings are immutable, so they behave as pure values.

Are functions mutable?  the code itself is immutable, the only mutable
things are the upvalues.  But if two functions share the same set,
then even if they're distinct, they would "change" together.  So it
makes sense to make them indistinct.

But so far, this has been considered mostly an optimization, not a
design feature.  So if it's more expensive than worth, could be
removed.   Or not.  Neither behaviour is a "bug".

personally, i do like the 5.2/3 behaviour.  seems more "pure".  but
relying on it is asking for trouble.  better be explicit and don't
repeat the definition if you want the function to be the same.

--
Javier