Built-in instance iterator

As a Roblox developer, it is currently too hard to write clean code for iterating over the children or descendants of an instance.

A new method could be introduced to the Instance class, which returns an iterator over its children:

local Model = workspace.Model
for child in Model:ForChildren() do
    -- prints the full names of all direct children of the model
    print(child:GetFullName())
end

It could also accept an optional bool parameter, recursive, which defaults to false. When set to true, the iterator would iterate over all descendants of the instance, rather than just direct children:

local Model = workspace.Model
for descendant in Model:ForChildren(true) do
    -- prints the full names of all descendants of the model
    print(descendant:GetFullName())
end

Alternatively, this descendant iteration could be broken off into a separate method, e.g. Instance:ForDescendants()

Iteration over the children or descendants of an instance is a common pattern, and this would help to support this pattern by making the code more concise and readable. Compared to the current method of passing the result of GetChildren or GetDescendants into pairs, this solution cuts out a lot of unnecessary visual noise.

An alternate solution which sometimes comes up is allowing tables to be directly passed to a generic for loop. I generally disagree with this solution, and prefer this solution as it achieves the same level of conciseness without fundamentally changing how a core Lua feature works.

Feel free to leave your own ideas and criticisms below :slight_smile:

3 Likes

I understand this is an older post, written before the introduction of Generalized Iteration, with the goal of improving ease of writability. However from an engine user’s perspective, it seems reasonable, in cases where reliability is not a concern, to question the existing practice of first building a table to iterate over, in favor of enabling direct iteration.

Problematically, the existing means of retrieving descendants (:GetChildren() and :GetDescendants()), are for lack of better description, all or nothing. As a developer however, I find I only actually need to concern myself with the full extent of these results, in algorithmically worst-case scenarios.

As such, I propose a method similar to the existing next global, for directly iterating over the children of Instances. If there existed some API of similar construction to Instance:GetNextChild(LastChild), it would enable developers to create their own iterator functions, which may be most appropriate for efficiently addressing the unique demands of their project’s organizational structure.

4 Likes