Tue May 4 10:32:20 EDT 2010
More DAG interface
More milling of the previous post. Let's add some heuristics to that.
The functional view is easiest to use, meaning, it _reads_ easier as
it is based on _lexical scope_. The graph view is more interesting
for program manipulation, and for graphical depiction.
Question: how to convert function view to graph view? I.e. given a
f (x,y) = (x/l, y/l) where l = sqrt (x*x + y*y)
How do we bind it to some combinator that has explicit node
references? Could the graph view be just an interpretation of the
Essentially, what we want is to convert from function to Arrow
representation (with explicit outputs) and back. Efficiency is not an
issue on the Haskell side, but the eventual C code generation should
eliminate all abstraction overhead.
So, let's find a way to compose two copies of f as an Arrow
So, Arrow is an interface. What are we going to use it for?
Essentially, we want to make something that has its _compostion
exposed_, i.e. a data struction. Simply composing functions hides the
internals; we want to look inside.
This seems to be the essence, wether to expose composition, or make it
implicit. .e. it should be possible to "flatten" a network into a
Representing networks: let's take the simplest approach: a collection
of functions, and connectivity information.
So, what is a DFN? Let's use the simplest, concrete data
representation and worry about functional abstraction later.
-- a set of nodes.
-- a set of processor instances. an instance is a relation from
nodes to functionality (a pure function).
Since this represents a graph, some form of de-cycling is necessary.
Note that the same is necessary for flat files! In essence: we are
building a data structure that describes a network as a flat
structure. There are two options: a zipper, or a dictionary. The
former might be interesting for traversal, but not for external
representation. The latter seems the best no-surprise option.
Let's stick with the Pure Data patch format, ignoring the graphical
information. The basic elements are:
object <name> [<arg> ... ]
connect <ob_id> <out_id> <ob_id> <in_id>
The identifiers are indices into sequences of objects, inputs and
outputs. This is an imperative description; i.e. a network is
represented by how it is incrementally constructed.
So, the main question: how to evaluate this imperative description?
Can it be done incrementally? Does it make sense to reprepresent it
in a different way that can be easily serialized to/from this
I'm getting side-tracked. The Pd format is not what I want, it's too
lowlevel. What I want is: black boxes with inputs and outputs that
can be composed.
So, the elements again:
- functions, probably :: [Float] -> [Float] as it will become
difficult to hard-code the number of ins/outs generally
- nodes, connected to a single generator, with multiple consumers.
this is the source of non-directedness (2 ways of traveling the
What seems to be clear is that the only simple representation is to
stick with functions, or any kind of textual representation, and find
a way to represent fanout. Inputs you can just "pass in" anyway in
the functional representation.
What about this: convert a structure which has outputs represented
lexically, to one that doesn (i.e. behaves as a function).
Essentially: ``introduce (single) assignment''.
Maybe that's the real problem all along. Some kind of functional
representation of assignment.