• Subject: Re: Table traversal
• From: David Manura <dm.lua@...>
• Date: Sat, 12 Nov 2011 17:18:36 -0500

```On Sat, Nov 12, 2011 at 3:03 PM, Dirk Laurie <dirk.laurie@gmail.com> wrote:
> A possibly useful addition to the repertoire of table iterators is
> "traverse", which recursively visits every non-table value in a table
> and returns not that value but a key-table pair (k,s) so that s[k]
> refers to the table entry.  This can be extended to allow the cloning
> of table structure and the simultaneous traversal of several tables.
> For example, this is a deep table copy:
>   t2={}
>   for k,s1,s2 in traverse(t1,t2) do s2[k]=s1[k] end

It shouldn't be necessary to create a coroutine on each node
traversal.  Here's a simpler example (for illustration):

local function traverse(o, f)
if type(o) == 'table' then
for _,v in ipairs(o) do traverse(v, f) end
else
f(o)
end
end
local function traverse2(o)
local co = coroutine.wrap(traverse)
return function()
return co(o, coroutine.yield)
end
end
local t = {3,4,{5,6}}
for o in traverse2(t) do print(o) end  --> 3,4,5,6

Here `traverse` is your typical call-back based recursive tree
traversal (without any coroutines), and `traverse2` transforms it into
an iterator by inverting the control with a single coroutine.

I also question how often the behavior "t1 is cloned into
t2,t3,...,tn" would be used.

A tangential note: Fabien recently posted on the design of a tree
traversal API [1].

[1] http://metalua.blogspot.com/2011/10/treequery-dsl-for-syntax-tree.html