Tables in Lua are still costly, but most objects we use need tables whose list of keys are most often constant over time. adding a <const> declaration inside a Lua module will instruct the symbols table of the module that some keys are contant and can be cached. These <const> declarations are still not part of the exposed API of the module, they are internal to the module itself, but to make sure they are valid and don't require runtime checks, they ensure that the assigned symbols cannot be removed and will stay at static positions
it may just happen that some key may receive a nil value, however the binding of this valuer will not drop the symbol, i.e. the entry in the equivalent table, so that dynamic lookups are not longer necessary: Lua already supports this by design in its tables that have two parts: an indexed part and a hashed part. However, the indexed part does not allow any position to be assigned a nil value, so that this creates an assumption if foreach-loops using ipairs(): nil-value checks are not performed when enumerating a table in the indexed part (and there's no nil-check when enumerating with pairs() the hashed part, but such nil check exists in ipairs() to determine when terminating the enumeration).
Lot of costly operation needed for dynamic languages can be optimized using "ghost" tables, notably it allows transforming dynamic typing automatically into static typing, it allows dropping many costly type inferences (frequent in Lua, including in the Lua code itself: ghosting tables would accelerate these by elimination of dead code, when it knows that some tests are always false or true inside the constraint set by the "ghost" table). However it requires developing a stronger JIT compiler in the VM itself, and would make Lua larger and more complex and not suitable for small embedded systems (but today most embedded systems are much more capable than what they were in the past, they have decent processors, often have mulitple cores, and more memory; the only limitation is for embedding Lua in a server-hosted container serving lots of queries, that's were there are limitations in terms of storage space in memory and CPU usage, and where a JIT is generally dropped, such limitation generally does not affect client systems (e.g. mobile hosts, whose own capabilities are now much larger than what a server would allow on a shared service used by lot of clients, possibly millions).
Do we need these <const> declarations ? No if we have a full JIT integrated. But yes to allow a partial JIT support that could save resource: explicit const declaration can hint directly the compiler with only a small price (checking dynamic propertoes to make sure that ghost tables are still valid, and then allow recompilation and caching again of the compiled code). Such strategy works very well inside Python (it just requires storage space for precompiled .pyc modules in a cache).