-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
vim.iter
with non-list tables (as a replacement of vim.tbl_flatten
, etc.)
#28777
Comments
It does clearly have some valid and useful use cases, as we can see. So probably something we should support.
I am less sure that
I was just looking at the vim.iter implementation again and I am wondering if it might actually be possible to support lists with holes. Currently we do this to determine if we can use the list optimizations: -- O(n): scan the source table to decide if it is a list (consecutive integer indices 1…n).
local count = 0
for _ in pairs(src) do
count = count + 1
local v = src[count]
if v == nil then
return Iter.new(pairs(src))
end
t[count] = v
end
return ListIter.new(t) But the list optimizations use a bunch of regular |
Adding it here as it seems to be the best available place. As |
This issue would be more like a discussion, only stating potential issues from the perspective of practical user experience without a clear solution yet.
TL;DR)
vim.iter
have some practical problems when dealing with non-list tables (or pseudo-lists that containsnil
as element), we might want to improve for better usability.Problem
vim.tbl_flatten
has been deprecated since nvim 0.10+ in favor ofvim.iter
, but what is suggested ---vim.iter(...):flatten():totable()
is NOT a exact drop-in replacement ofvim.tbl_flatten
.A corner case is when the table is "not a list", e.g. containing a
nil
values:... because
vim.iter
treats list-like tables and non-list-like tables (i.e. maps) differently:This is due to the limitation of the Lua language that Lua table does not distiniguish map and list(array), so a valid list contains. While this is actually an intended, correct behavior, given how Lua works, for users and laypeople who are not very familiar with Lua the behavior can be confusing: because
totable()
returns a list of (key, value) tuple for non-list-like tables.Remark: it was an undefined behavior of
tbl_flatten()
Actually, the use of
vim.tbl_flatten()
for tables that are not list-like (e.g. includingnil
as a member) was never specified:However, it is worth noting that
vim.tbl_flatten()
is often slightly abused in the wild to filternil
values while doing flattening:Note: the behavior of
vim.tbl_flatten()
on such 'lists with holes (nil)' is not very accurate (as of nvim 0.10.0); it's not a 100% correct replacement of "filter nil values and then flatten":Potential impact:
Starting from the 0.11-dev (nightly) versions users will experience a looooot of deprecation warnings on the deprecated APIs,
vim.tbl_flatten
,vim.tbl_islist
, etc. There are actually a lot of plugins that are still usingvim.tbl_flatten
which was deprecated only very recently. So plugin authors should migrate tovim.iter
-based solution (unless we make additional changes) and remove the use of deprecated APIs sooner than later, but the subtle difference can lead to (minor) bugs.Possible solutions
Either:
nil
in a list is an anti-pattern ?!flatten()
for non-list-like (dict-like) tables.vim.iter
API to makevim.iter(table):totable()
return a "map" instead of a list of (key, value) tuples.vim.iter()
to handle lists with holes as wellfix(vim.iter): enable optimizations for arrays (lists with holes) #28781
References
The text was updated successfully, but these errors were encountered: