On 2026-04-09 18:01, Rett Berg wrote:
>> __index and ___newindex are called only for not-found key.
> Why this non-existence criteria? Why not throw them away in 2026 and
> add read and write wrappers for table slots? Like OnRead(), OnWrite()
> (or __read, __write if you like underscores)?
>
> I*believe* the reason is performance. __update would require the write
> path to_always_ check for the metamethod even if the item was there,
> whereas __newindex only requires checking it in the nil case, which is more
> rare for common well-formed tables.
>
> So in the current common case the write path looks like this:
>
> find slot
> if(slot filled) put in slot
> else {
> find newindex
> if(has newindex) __newindex(self, k, v)
> else put in slot
> }
>
> Update would require the "find update" to be moved up, which would reduce
> performance for the common case I mentioned.
>
> [...]
> Just some thoughts,
> - Rett
Hello Rett,
There is no sense of talking about performance without use cases.
Yes, __newindex code path is faster without __update. But what outer
code does?
If it just handles allocating new slots then no __update is needed.
We have __newindex. This proposal is "considered harmful for performance".
But what if we want to handle all writes to table say for debugging mode?
Currently we will create empty "proxy" table, store real table in closure,
and use __newindex again. Ugly but works.
With proposed __update we will use real table and use __update and
__newindex. Code duplication but okay.
If __update was proposed to replace __newindex then we will just
use real table and __update. Neat.
-- Martin