although that's crazy by itself, as then the runtime would have to check for
every access that might modify the table, or elements it refers to. And
still it won't work:
const set = { t1, t2, t3 }
t1[ #t1 + 1 ] = ""
Take it a little easy to call things "crazy" sooo fast. There is a
difference between frozen and deeply frozen, and proper
implementations have no problem to know which parts are frozen and
which aren't and to make the right optimizations on that. In you
example the expression "#set.t1" can partially lifted by the compiler
out of loop since set is non to be immutable, it does not need to
query the set table in every loop, since its immputalbe. It simply can
directly call #t1, which it needs to, since that one is not immutable.
The mass of benefits you get depends on the mass of things you allow
yourself to be set immutable.
To put this in lua, I guess the runtime has to "mark" things as constant, which might be costly.
Its 1 bit. Yes you pay something on the one hand, but on the other
hand you get large benefits, if done correctly.