> One could imagine a mechanism where tables get locked - new keys are not allowed to be added to locked tables, but existing keys could be used in the usual way[
Just set a __newindex metamethod for _ENV that raises an error.
+1. IMO Lua's scoping works great as it is. You don't need to do anything awkward to access globals like `print`, you can have multiple scopes with `_ENV`, and you can attach metamethods to those scopes (including the global one) to do clever things like warn/error on unexpected use of variables. You even can write `_G.x` if you want (or need) to clarify that you're accessing globals, and it's the same syntax as any other table access.
Lua's everything-is-a-table design is excellent, and I think people often don't recognize how powerful it is in its simplicity.