I'm beginning to find that with an increase in Vuo composition complexity comes an increase in the unwieldiness of working with Build List
and Process List
nodes. I was thinking of putting together a feature request, but given the plethora of potentially upcoming changes to lists, I thought a discussion might be a better venue in which to start.
Here are the issues I'm finding, along with workarounds and possible Vuo Editor improvements.
Too many required Hold Value
and Hold List
nodes
My issue
I'm working on a composition that has, in three cases, ten Hold
nodes (five with lists) to go with a Build List
node. Why so many? To improve performance, the composition crunches some numbers upon launching rather than with each requested frame. The result is lots of saved values coming in via these Hold
nodes.
My workaround I could (but won't) give up some maintainability by hardcoding in some of the values.
Potential solution
Given that Hold
nodes are required for event management when building or processing a list, this behaviour should be automatically provided. Perhaps when one connects "outside" data to a node "inside" a system of nodes building/processing a list, a hold node (and the appropriate cable connections to make it work) could be automatically inserted, in the same manner that conversion or rounding nodes can be automatically (or nearly automatically) inserted.
Events management with incoming data
My issue
I have two lists that are built in parallel upon launch. Both of these lists are then used, in conjunction with Hold List
nodes, to provide data in the construction of another list. Because both of those "feeder" lists generate brand new, unrelated events, I cannot reliably execute the Build List
node at a moment in time when both feeder lists are complete. Roughly half the time, one or two iterations of the latter build are run before the incoming data is available.
My workaround
Abandon the idea of generating data in parallel and do it in series. Or set things up so the latter Build List
node executes when (and only when) a specific number of events have arrived at, say, a Count
node. The first suggestion is almost certainly the most suitable in most cases, for maintainability, but it would be so much more slick to be able to do them in parallel.
Potential solution
The best solution for me would be to have the Built List
output port fire not a new event when the list is built, but the same event that arrived at the Fire
input port. That way the events arriving in parallel will wait for one another before moving forward. An alternative solution would be to somehow give the Build List
node some way to keep track of the data required to build the list, and only execute once all the required data is received. (This second suggestion has the potential to open up a new can of worms, though, since some data required may not arrive as frequently as is required for the build, as some data could keep the same value for a while.
Debugging is very difficult when building/processing a list
My issue Clicking on a port within a build system displays only a single value at a time. When a 100-item list is being processed, it's impossible to look at individual pieces of data in place.
My workaround
Connect the output port of a node within a build system to an Enqueue
node. (The output port of the Enqueue
node leads to nowhere, but can be used to have a look at more than just a single value.)
Potential solution Enable a user to click on a port within a build system and see a list of values, matching the functionality of my workaround, but without the extra node.
So...
...what are the current plans for Build List
and Process List
? Are they going to remain as is, or are we going to start seeing nodes that we can "dive into", like QC's Iterator node?
Comments
@Pianomatic just rapidly read
Philip just rapidly read your discussion. Not deep enough to understand all your sub-problems and solutions though.
What I have in mind however rapidly is :
1 - Concerning Build List and Process List.
I remember Jaymie writing somewhere she hoped Allow changing single-value ports to accept lists (turn most nodes into iterators) would make it all easier for us to iterate (although I don't find her comment back right now).
There really are very much questions and "bugs" (which are not really bugs) and expectations about iteration and build lists and process list. They are aware of that I guess. So much of the things I try to achieve in Vuo could be resolved with that feature request if it works like I hope it to work. I recently have been submitting some questions as comments on that Feature request (Questions in comment). I have already pledged many votes for it.
Much of the answers and comments I post here when I try to help people are related to this problem too.
So somehow, that feature request doesn't have much votes yet, but I guess it is actually one of the most wanted feature of the community. I'm encouraging many people to vote for it.
What I think is that if that feature request works as I hope, Build list and process list will somehow be depreciated. They could still be in Vuo but I guess their usage will be restrained to specific things and most of our expectations will be fulfilled with automatic lists.
It could be much more powerful and easy to use then the iterator in QC I think !
Anyway, still there are some speculations here, only the team will be able to give you some real answers ;)
2 - Concerning hold nodes.
Just want to be sure you had seen the Allow feedback loops without needing a Hold Value node FR already.
Although it doesn't prevent the idea of an eventually automatic hold value like you mentioned.
The problem I have with those automatic additions is that I don't know if these are optional (should read the manual again, perhaps there is a part about that). I man what if one wanted extra events to come into Build list ?
@Bodysoulspirit - Yes, I've
Bodysoulspirit - Yes, I've seen the feature request you linked, and had linked it in my post above, along with three other list-related feature requests. That's why I'm wondering what list-building/processing will look like going forward. I find the way they behave very clear at this point, but it took me some time to sort it all out in my head, which seems to be the norm among us Vuo users.
To address your above points:
Giving nodes the ability to handle lists, and therefore act as iterators in themselves, is certainly a more intuitive way of handling lists, and could have the potential of rendering the
Process List
node obsolete-ish, but I'm not convinced it would cover every use case—probably more basic tasks only, but would it ever make it easy to implement lists! But theBuild List
node really stands on its own in terms of what it can do. I've been using it far more thanProcess List
because you can build a list whose size and contents can be defined by other data on the fly. Also, the ability to have direct access to the list index has uses that just can't be covered byProcess List
, such as using theGet Item from List
node to access corresponding items in several different lists.I hadn't seen the feature request regarding feedback loops, as I don't tend to use feedback loops very often, but I've noted the difference in how easily they're handled in QC versus how Vuo requires feedback loop handling. What I was referring to, however was the fact that
Hold
nodes are required when bringing data into the nodes used to build or process a list. Without using them, there can be extra events injected into the mix, resulting in what appear as jumbled up lists coming out ofBuild List
andProcess List
nodes. Jaymie does an excellent job explaining this behaviour in this Q&A, and I had personally run into trouble when unknowingly leaving outHold Value
nodes and filed this not-a-bug report. Both posts have broken and fixed versions of the compositions. Worth a look.@Pianomatic yes you are
Philip yes you are probably right, Build List may not be depreciated even with the "Allow changing single-value ports to accept lists (turn most nodes into iterators)" feature request. Could still be useful !
I also liked how Jaymie once used the "share list" node to a build simple lists. Merge XY, XYZ and "Enqueue" also are ways to create lists depending on needs.
;)
Appreciate the time
Appreciate the time Philip and Bodysoulspirit have put into this discussion. My comps are still frustratingly complicated even at the simple stages I'm working so far so i'm not going to weigh in on this discussion yet.
But if you think single ports handling lists will ease congestion, how about when nodes can output and receive Lambdas (passing functions as a datatype). So for example, a movie node could receive functions to play, play backwards, return playhead to start position, play at any given speed depending on the function sent to its playhead position port.
Also i can see Vuo node and custom node writing getting a whole lot more complicated if we have to anticipate input value ports processing lists. imagine a simple
vuo.math.add
node with two inputs and lists of integers on each input like soA:{2,3,2,3,2,3}
,B:{5,6,5,6,5,6}
. Does the output become{7,9,7,9,7,9}
or{(2,5),(3,6),(2,5),(3,6),(2,5),(3,6)}
? I guess the former but what if the lists are different lengths, does it add zero or drop the result? Lots of micro management and error handling (e.g. divide by zero) involved in lots of edge cases to work through, sounds like fun for team Vuo and any of us involved in custom node creation! :-)Love the comments under
Love the comments under "Debugging is very difficult when building/processing a list" Bodysoulspirit. Holding down a modifier key like "⌥" to see the list of values rather than the last value in a build chain would be very cool. It would make a big feature request in and of itself, I'll leave it for you to create as it's your concept essentially.
That's my only issue with QC iterators which i actually enjoy mostly, but inspecting a range of values requires use of the
Queue
patch and publishing the output, problematic if there's a render node in the iterator. Otherwise i like even nested iterators they do what they should mostly in QC and my head gets them.My feeling before Vuo was
My feeling before Vuo was even released was that to do complicated list building we would hit the C code and do it there. At a certain point literal code and the extra powers of abstractions it allows beats wiring nodal code hands down. Just a thought :-) I do appreciate this discussion though.
I appreciate how you spelled
I appreciate how you spelled out the issues here, Philip. I too am seeing how so many discussions/desires point in this direction. Seems like nesting subcompositions into the Vuo editor without having to save them to the node library might be yet another way to imagine iterations of iterations (like QC).
That bit about the sub
That bit about the sub compositions got me thinking..."what if":
I wonder how hard it would be to have a composition importer patch that would allow you to feed it a structure of floats, count X. Then, VUO loads that composition X times, giving each list index to each corresponding sub comp instance.
The data that each sub composition instance would output, would be gathered into a structure/list. These could then be accessible to the main composition.
It may be that iteration in VUO would work best using this sort of premise, perhaps being a composition protocol, limited to certain input and output data types...excluding windows and such.
@useful design - Regarding
Alastair - Regarding node-writing: once nodes can take on lists as well as normal values, I think it will depend on the details. Presumably the node-creator will be able to define whether the node will accept lists or just single values. What would be amazingly slick on Team Vuo's part would be if no extra code has to be written at all. Imagine writing an addition node that just takes two values and adds them. Then, if two lists come into the data ports, it just runs the node several times automatically and spits out a list instead of a single value. If it were handled automatically by Vuo, it would make it really no different from writing nodes now. You'd just get the extra functionality by virtue of using a new version of Vuo. For example, if differently sized lists show up, Vuo could just automatically execute the number of iterations required for the smallest list. I think this is the key to make it all work for folks that are writing their own nodes.
As far as error handling, I've noticed Vuo handles all the error cases I've inadvertently thrown its way automatically, such as dividing by zero. Very little seems to make a Vuo composition crash and burn.
Build chain inspection: My feeling is that it's rarely useful to inspect a single value inside a build chain, so I'd say to just do away with the modifier key and make inspecting the whole list of result the default (or only!) behaviour. In QC I remember inspecting values inside iterators, and it would just give you the last value. It has some use, but compared to being able to see the entire list of values, it's virtually useless. At least in Vuo the
Enqueue
node can be implemented inside a build chain without the rendering/publishing-related complications imposed by QC's iterator.Complicated list building: I had the same feeling, but was hoping we'd get something akin to QC's Javascript patch. I used that patch constantly, usually as the logic of the program, and using the rest of QC's capabilities to deal with rendering. But, I've been delighted as of late as to the wide range of stuff we can do with Vuo's
Build List
node. I'm just finding the way we have to work with it frustrating, hence the suggestions like automatically insertingHold Value
nodes where they'd be required anyway.@George_Toledo - It sounds
@GeorgeToledo - It sounds like you're describing a way one might use the
Build List
node. Have a look at this image, and please clarify if I have it totally wrong.Edit: The event cable going into the
Build List
node's refresh port really should be going into itsFire
port.Screen Shot 2016-02-27 at 19.31.44.png
That is close to the concept,
That is close to the concept, but that looks like it would be processing data in a consecutive order, building a list element by element. Which is good for some scenarios, not for others.
I'm attempting to describe that a hypothetical subcomposition node, could output list data as a parallel process - all of the data in one shot, by having a composition execute inside of a loop, in the internal code of the node.
Whatever the iteration count is, is how many times the subcomposition would execute per evaluation cycle, and it could theoretically be possible to output a list of that same amount of components.
I think, and i'm not certain
I think, and i'm not certain here, but i think that Vuo can multi-thread with it's
build list
andprocess list
nodes. The way George describes theiterate with sub-composition
node is conceptually (for the Vuo user) quite close to QC iterator patch, except it happens in a separate sub-composition not inside a macro. I wonder if you could put a seconditerate with sub-comp
inside the first one… what if it was the same composition… recursion, yay! I guess the problem of having 1D Lists limits iteration within iteration to some extent unless all the output gets appended to the same list.Yes, i can see a time when
Yes, i can see a time when certain nodes will be automatically added where required like
hold value
. I'd like to see the represented with smaller symbolic nodes not entire node blocks just to clean the graph up a bit. Agree with most or all of your comments above.Yes @Pianomatic, i can see a
Yes Philip, i can see a time when certain nodes will be automatically added where required like
hold value
. I'd like to see the represented with smaller symbolic nodes not entire node blocks just to clean the graph up a bit. Agree with most or all of your comments above. Having Vuo do list wrangling without effect the writing of simple stateless nodes would be awesome indeed but perhaps a big ask on Team Vuo.Our (Team Vuo's) plan for the
Our (Team Vuo's) plan for the future of
Build List
andProcess List
is to replace them with something better — Allow changing single-value ports to accept lists (turn most nodes into iterators) and eventually Ability to pass entire subcompositions into other nodes via cables (function ports / lambdas / closures).Basically, the idea is to wrap the nodes you want looped inside of a subcomposition, instead of a feedback loop.
Philip, I appreciate your thorough and organized explanation of the issues.
Too many required Hold Value and Hold List nodes — Allow changing single-value ports to accept lists would remove the feedback loop and thus the need for Hold nodes to regulate the feedback loop.
Events management with incoming data — Allow changing single-value ports to accept lists would also help with this, assuming that multiple ports on a node could be turned into lists. (See recent discussion on that feature request.) There would still be the issue that the node would execute twice, once for each of the separate events. The workaround with the
Count
node would still apply. (Would a node similar toAre All Hit
, but accumulating events from different sources until all inputs have gotten at least one event, be useful?)Debugging is very difficult when building/processing a list — I like the idea of popovers providing the aggregated list instead of the one item. That would be possible to implement if built on Allow changing single-value ports to accept lists and Open subcomposition in same window as composition (specifically the part about using popovers inside of subcompositions).
For
Process List
, I think any nodes you could put into the feedback loop, you could also put into a subcomposition. So that should be covered. (But let me know if you think of any exceptions.) ForBuild List
, that could be replaced by feeding a series of numbers (the iteration indices) into the subcomposition. We'd have to add a node to easily generate the indices, since the closest we have right now isMake Points along Curve
.Our plan is to put the work on the Vuo compiler, not on the person developing nodes. If a node had one or more ports expanded into lists, then Vuo would automatically execute the node N times and aggregate the results into the output list of N items. For stateful nodes, Vuo would also automatically store N different instances of the node instance data.