Skip to content

A rule for removing (converting) generalized iteration #203

@sircfenner

Description

@sircfenner

See #202 for motivation.

An implementation I have done in the past converts the following:

for x, y, z in input do
    print(x, y, z)
end

into:

local _iterator = input
local _invariant, _control
if type(input) == "table" then
	local _mt = getmetatable(input)
	if type(_mt) == "table" and type(_mt.__iter) == "function" then
		_iterator, _invariant, _control = _mt.__iter(input)
	else
		_iterator, _invariant, _control = pairs(input) -- !
	end
end
for x, y, z in _iterator, _invariant, _control do
	print(x, y, z)
end

This may not be 100% correct but could be a good starting point.

As it can't be determined statically whether the subject of iteration is (1) a plain table, (2) an iterator function, or (3) a table with an __iter metamethod defined, it is necessary to insert a runtime check.

Notes:

  1. Using pairs(input) does not necessarily conform to the order of Luau generic iteration (for example, consecutive array indices starting from 1 go first)
  2. Doesn't handle iterating over userdata (with __iter defined), which is supported by Luau
  3. There may also be issues with accessing __iter if __metatable is set

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions