How to write type-stable dataflow graphs

While you have an acceptable answer here (branched dispatch based on type checks), you achieve what you want which is full compile time optimisation of the graph. The secret is to not use a Vector to hold children that are also execution nodes, but rather a Tuple that you can specialise on for dispatch. A vector always resolved to a single type for all elements in the container, whereas a Tuple is concretely typed for each element.

I suggest looking at Chain from Flux for some ideas (Flux.jl/basic.jl at master · FluxML/Flux.jl · GitHub), plus some of the answers I was provided here Executing array of functions much slower than executing functions in series

The intuition to develop for Julia is that containers of heterogeneous types for method dispatch will always come at a cost and there are three options:

  1. Use FunctionWrappers or similar to stabilise the function interface, at the cost of no possible inlining
  2. Manually dispatch based on types (i.e. write your own basic interpreter)
  3. Lift the entire execution graph into the type system, usually by using Tuples and dispatching on each peeled off element

There are other strategies I’m sure but that’s what I’ve run in to. Strategy 3 is highest compile time overhead, lowest ringtone overhead, but also most difficult to grok :slight_smile:

1 Like