Yes, in fact that will be part of my PhD :-)
State / Processing
I don't think we'll ever be able to marry the stateful model of Processing with the functional model of NodeBox.
The idea when writing that blog post was about allowing users to write nodes in Processing, and have them integrate with the rest of the system. However, as is clear, since the functions in Processing set state or draw stuff directly, there is nothing to integrate. We could still choose to use Processing as a drawing API, but this negates all the benefits of using Processing (you can't really wrap existing Processing code in nodes, for example).
Variation
If your whole model is functional, how do you generate variation? How do you do this typical for (i=0;i<size;i++) loop where i will determine the size of the shape, for example?This is where NodeBox 2 and NodeBox 3 differ fundamentally. In NodeBox 2, we used this principle called "copy stamping" (inspired by Houdini) where we would travel back up to the nodes to modify them, then go down again to render them. It requires users to input expressions to generate variation. The idea was for the expression to be a gateway drug into "real" coding. However, the expressions just became unwieldy.
In NodeBox 3, as you know, we moved to list matching as a way of generating variations. If you want alternating colors for a grid of rectangles, you provide a list of colors that you want to alternate between and a list of points for the grid, and NodeBox will match them up. This works much better in practice, especially for data visualisation.
Feedback loops
Let's think about the stateful nature of feedback loops like boids. Since NodeBox is functional, the side effects of a function (like the new position of each boid) can't be stored inside of the node. Each node should be a deterministic operation, where the same input always leads to the same output.
This is an issue with functional programming in general, and we can look towards other functional languages to see how they deal with it. Which leads us to.... monads!
The Haskell state monad is a solution to our issue. In NodeBox, we can implement this quite cleanly using a "state" port that takes in the previous value. This works well for small examples like counters, etc. Bigger networks, with multiple independent states, are much trickier and often impossible.
Another issue is with subnetworks. If the state is in the subnetwork, we don't want to use the same state every time. We really want a different state "instance" for each run through the subnetwork. We can solve this (though we haven't yet) using a path-based approach, where we tag on the path that we've travelled through the network. Something like root.subnet1[5].counter. (Again, this is fictive since we haven't implemented this yet).
Note that monads aren't the only solution. Clojure, for example, manages things fine without thinking about monads. However, in those cases the code you write looks more imperative than functional. Maybe this is a solution as well: allow for a bit of imperative code to sneak in to fill in the conceptual gaps of functional programming.
Subnetworks
Which brings me to subnetworks. The way nodes are processed in NodeBox Live is nearly identical to how we do it in NodeBox 3, except for subnetworks.
What I've found is that each time we invent our own visual thing that has no analog in textual coding (like subnetworks, or copy stamping), we get into trouble. A better solution is to use systems that we have in the textual world and appropriate them. That's why we use regular functions in NodeBox Live instead of subnetworks.
This gives us some nice properties: we have a list of functions that we can re-use all over the place. Functions can be written visually and functionally, and they expose the same interface (multiple arguments in, one argument out). In fact, visual functions get compiled to JavaScript functions (we still need the NodeBox runtime, but we can mostly get rid of that as well if we want to).
External input
This all works fine when we're dealing with inputs generated inside the computer. External inputs still present a problem.
NodeBox "pulls" data from the bottom node to the top node, using as much cached data as possible. Since external input comes from the top, we have an issue. We would need to make nodes that take in external input dirty, then propagate that dirtiness to all downstream nodes, until we reach the rendered node. We'll also have to figure out a way to make these external inputs available: a simple solution is just to expose a node with no inputs. We already do this for mouse and OSC.
External output
We would also like to be able to let our networks have effect on the outside world: think about steering an Arduino robot, or sending OSC events to PD,... This requires our networks to have side effects, which goes against the fundamental nature of functional programming. Specifically, it breaks the single "rendered node" approach: what node should the rendered node be? If the "send OSC" node is rendered, we don't see any visual output.
We currently don't have good solutions for this. One hack is to put a "send OSC" node in a combine node. It doesn't return anything but it still gets executed. However, this is a big hack and one I'm not a fan of. The "order number" from the NodeBox 2 post might be a solution, albeit a quite difficult one.
Conclusion
There are probably more issues we have to tackle, but they all come back to trying to pigeonhole functional programming onto a computer architecture that is fundamentally imperative. Note that I'm not bashing on FP: functional programming is very attractive for most of the things we'd like to do with NodeBox, like visualisations or generative designs. However, some issues lend themselves much better to imperative code than to functional code. The processor in our machine is fundamentally about manipulating memory, and hence, changing state. Any deviation from that imperative model will require thinking about how to manage state within that model.