The Object Network

ONF: Object Network Format and Functional Observer

This page describes the core innovation of the Object Network: the Functional Observer dynamic object model - "links to live stuff".

Functional Observer describes a linked object graph structure - the Object Network.

Objects are lists of properties - mapping from property name to value or values. They can be found on links or UIDs and are generally persistent - saved to disk.

They are active and autonomous, observing each others state through their links and updating their own state accordingly.

Data representation

Here's an example showing part of an ONF object:

{ UID: uid-111
  Version: 3
  Notify: uid-222
  Alerted: uid-333
     :
  b: x uid-333 123.4
  d: true { .. }
  p: uid-222
     :
}

Objects have a header section distinguished by capitalised property names. This contains the UID of the object. All Object Network objects have UID object references which will usually contain a GUID, a UUID, an IPv6 address, or some other random-looking string after the "uid-" prefix.

It also contains its incrementing version number, that changes with every state update. It may have a property that lists the uids of objects it wants to notify when it changes, plus one showing incoming notification alerts.

A property in a property list can have one or more values in an ordered list, including nested property lists. Links to other peer objects are just UID strings as values after a property name and can appear anywhere in an object.

Functional Observer

These objects interact by mutual observation. The Functional Observer interaction model is simply:

Set an object's state as a Function of its current state plus the state of other objects it Observes through links.

Such a programming model is declarative in nature, and thus very expressive, as well as being naturally concurrent.

The implementation of Functional Observer is very simple. Initially, an 'evaluate' function on an object will be called, triggered by: object creation or re-cacheing; a pushed incoming state change on either a previously observed, linked object or an unsolicited, unobserved one; programmatically, on new input state, etc.

Then the object will go around scanning links to observe, and pulling state on which it depends, to decide what its current state should be, or what its reaction will be to an incoming new state. When it changes itself, its version is incremented, it's saved to disk, then its new state gets pushed on in turn to the objects that have observed it.

In other words, an object can "look through" its links to view or pull in the state of a peer object. The act of scanning an object through a link (or link chain) sets up the observation of that object's next update. Subsequently, observed peer objects will push updates to the observing object, allowing it to continue to update its state accordingly.

Hence the observation of any linked object can occur either by pull - the observer reads the state of the linked target object when needed - or push - the target pushes its state to the observer when it changes. This can thus support both lazy and eager programming models.

An object observes the links it visits in this process, and conversely, if it no longer visits a link, it stops observing it. An object that falls out of the cache through lack of use may also stem observation of its dependencies. Some objects may allow themselves to be observed at any time, some only when they have re-evaluated themselves by observing their own dependencies.

An important constraint in Functional Observer, that is needed to allow distribution over the network, is that observed objects don't get to know what other objects are observing them.

However, an object may spontaneously push its state unasked to a peer object - held in the Notify: property above. Object 'A' can make itself known to another object 'B' that doesn't yet have any link access to it, by pushing itself to 'B' unasked. Object 'B' can then set itself up as an observer of object 'A' if it then adds a link to 'A' and carries on scanning it.

An object can optionally see what changing objects have caused it to be brought to life to re-evaluate itself by looking at the list of links in the Alerted: property above, which is also where it discovers any spontaneous or unsolicited notifications. It needn't look at this list, but if it does, peeking "through" the links there don't cause observation as in the normal link following, allowing the object to screen unsolicited objects.

Detailed Object structure features

Single elements and lists with a single element are not distinguished. There are no duplicates allowed in property name labels. Properties are ordered, meaning that random re-orderings of properties due to hashtable algorithms won't occur, and properties are generally dealt with top-down. Numbers aren't restricted in range. ONF is always encoded in UTF-8 when serialised.

Links are transparent: so any object linked to can be merged in-line instead:

uid-111:

{ b: c  f: uid-222 }

uid-222:

{ a: x  b: e 123 }

=

{ b: c  f: { a: x  b: e 123 }}

Links to list objects are also seen as the same as inline lists. For example:

{ .. email: uid-111 .. }

uid-111:

{ is: list  list: a@b.com c@d.com }

=

{ .. email: a@b.com c@d.com .. }

This allows lists to be grown outside of their containing object, or reduced back in again. An object can switch at any time between these forms: single-to-list-to-single, link-to-inline-to-link.

There are no nulls or empty lists in the Object Network, or rather, null and empty list are equivalent to non-existent. So:

{ a: null  b: null c }

=

{ b: c }

Objects (and sub-objects) can link to "further details" using More:

uid-111:

{ b: c  More: uid-222 }

uid-222:

{ a: x  b: e 123 }

=

{ a: x  b: c e 123 }

The elements at 'More:' are merged in set-wise: duplicates are removed.

Paths into and across objects

ONF also defines a path notation to drill into and between objects. Given:

uid-111:

{ b: x  c: uid-222 { d: 22 } }

uid-222:

{ a: y  b: z 123 d: 33 }

Various path expressions, beginning with "@", pull out each value:

 @b:    = x
 @c:    = uid-222 { d: 22 }
 @c:a   = y
 @c:1:a = y
 @c:b   = z 123
 @c:b:2 = 123
 @c:1:d = 33
 @c:2:d = 22
 @c:d   = 33 22

Links are transparently jumped. Lists are indexed from 1. Lists may be transparently jumped in the course of evaluating a path, in which case, the result is a list containing all the ways the path matched.

Duncan Cragg, 2016

Contact me and/or subscribe to my blog and/or follow me on Twitter.