We have a similar model, but use a function / filter graph, ala ltn12,
but not implemented that way.
Basically, you have a bunch of functions, but they're actually tables
with the __call method defined. You connect them with an "add_target"
method such that the return statement calls the next function or
functions (in the case of multiparented graphs, where one function
triggers multiple filters down the line).
You can store a "step" value in the argument list to the connected
function, if needed. This comes up for us when the graph is a tree of
some variety.
When there is one source, or starting function, you can pump the
source: call the source function and trigger tail calls.
If it is a tree with multiple children per parent, then we tend to call
the final function (root / sink) and have it call its children,
processing their return values and then passing the output back. Since
all of the functions in the tree are doing the same thing, recursively,
the effect is that you get the output in the order that you expected.
Children that are not parents need sources, which might simply be
functions that pass back raw data when they are called, which makes
them look like plain filters to their parents.
Hopefully this is helpful. :)