Skip to content

Value semantics

This MR changes a lot in itable's internal implementation:

  • itable{a = {b = 42}} is now processed by deep copying all of the tables
  • Calling itable multiple times with the same table will always produce the same itable object until the garbage collector clears the original table.
  • Public API changed:
    • deepcopy removed, use itable or itable.from
    • eq removed, use = or rawequal
    • immutable removed, use itable or itable.from
    • from added, an alias to a direct itable module call

Value semantics

In Lua, evaluating the same table literal twice will produce different objects:

> {1, 2, 3}
table: 0x56391fe3a100
> {1, 2, 3}
table: 0x56391fe3a3e0

With itable, the resulting objects will be the same:

> itable{1, 2, 3}
itable: 0x564041fe5560
> itable{1, 2, 3}
itable: 0x564041fe5560

A new object may be constructed if the garbage collector collected any older references to this data structure:

> x = itable{1, 2, 3}
> x
itable: 0x564041fe5560
> collectgarbage()
0
> itable{1, 2, 3}
itable: 0x564041fe5560
> x = nil
> collectgarbage()
0
> itable{1, 2, 3}
itable: 0x56404203af70

Because of this, testing two immutable tables for equality no longer requires deep comparison. Immutable tables can be used as keys in other tables with equally fast lookups to regular Lua data types.

Memory usage

This change can severely impact memory usage. This still needs proper measurement, but beware that to implement value semantics, all tables are serialized and interned in a weak table. The garbage collector can still collect unused objects, so the table holding interned values will not grow forever, but if a lot of tables are retained, memory usage can spike.

Merge request reports

Loading