Rectangles

Input

JSON


            

Output

SVG

notes

  1. want to simplify the d3 expression; too much repetition of property/attribute names. will have to extend d3 a little to do that.
  2. move input rendering to d3, see how that looks
  3. It's interesting that the argument to 'append' cannot be a function in D3
  4. My computer gets slow around 2000 rectangles, but still usable.
  5. model an html table
  6. Occasionally the first rect glitches out. why?
  7. Move dev to localhost, to avoid codepen nastiness (slowness, unreliability, etc)
  8. Add alternative interpolations for color
  9. Add alternative orderings (spiral, concentric squares, stripes, hilbert space-filling curve, etc)

The data-structure here is your basic n-ary tree, with a few twists. I wanted absolute simplicity, so child nodes point to the parent, but parent does not maintain a list of children. It can be imagined as something like a sponge, taking in arbitrary information and plopping it in just the right way, with a satisfying snick. We keep the data in a grid, filled in starting with the top left (the root, at 0,0).

The root is the Primordial Start event. At first, this refers to this session. Later, after recovering state and resuming, we place ourselves as a later event in a longer process. We effectively "zoom out" of this process, and consider the timeline of behavior of the process through time, across sessions. I call this process a "Durable Process". Canonically, prior state is stored as a sequence of objects representing input. Two kinds of objects, measurement (which is precious) and reaction (which is not). And how remarkably often "measurement" refers to previous measurements!

Universal Data Language: Declarative. Reversible. Beautiful.

Simpatico. A singleton object that serves as the representation of the current, short-lived Process, and the machine's ability to spawn new Processes, simulated as new Cores. A new Core is produced when an input has two possible inputs leading out from it. One place this happens is object instances, where their state diverges with unique input. The class is the first input, and the new keyword lead to subsequent, diverging inputs.

Class (and object) versioning. A "Class" in Simpatico is just a related set of Handlers. A Handler is a special measurement, of the programmer's mind, consisting of an object that describes how to react to input within a context. The reaction can only be a list of objects. These objects should either be UDL or handler invocations. Handler invocations may call each other, resulting in a message cascade. After the cascade is exhausted, the core's residue is in the correct state. At the top-most level, we add a library of handlers, then we add a library of types (different sequences of handlers). Finally, we add instances of types to the type-tree itself. In this way, even "instantiation of a type" can be expressed as simply targeting a valid (meaningful) parent.

Instantiation shares a lot with the Primordial Start Event. We are interested in when it happened, and also in the casual chain that led to it happening.

The final pieces to the puzzle. Handlers return detailed "error" result when information is wrong or missing when it was invoked. An appropriate data-structure should be general and highly declarative. So I developed a system of Compound Predicates which is a data-description language, written "with the grain" in modern JavaScript (ES6). This implies that a Handler should be able to execute with only one argument (the context) and compute this data-structure.

Observers allow side-effects to happen when local state actually changes. This targeting is done in a declarative, but usual way (e.g. a sequence of property names and array indices, or a pattern, applied to a root). Observers can be disabled and then reenabled, which is handy for reviving objects from the log. In a symmetrical way, Helpers are disabled and then reenabled last. (Durable Process without revival: do stuff, save state. With revivial: load state, do more stuff.)