Armstrong Consulting
1200 Dale Avenue #100
Mountain View, CA 94040

Date: Wed, 18 Oct 2000 17:04:13 -0700

From:   Eric Armstrong

To:     unrev2,

Subject:   Architectural Snag


Thanks for the encouragement. [in your letter yesterday


The architecture I've been working [reported in my letter yesterday] on hit a big snag in the last couple of days. The issue revolves around the difference between links that are included as part of a node's text content, and pointers to contained substructures that are included in a node's sublist.

The problem has had me flumoxed enough that I began writing this message to describe the problem. In the process, I've come up with at least one technical solution, but it implies the need for two different ways of creating links that will be very similar, but subtly different. So even if the implementation makes sense, will the functional behavior be reasonable??


The fundamental design consists of nodes and lists. Lists contain nodes, and nodes have one or more lists. So far, so good.

A node can even have multiple parents, by replacing the usual "parent pointer" with a list that points to all of its parents. When moving or removing a node, the move always occurs in some viewing context, defined by the list that the user is currently displaying. Still, we're good.

The system also distinguishes between the "content" subtree and the "structure" subtree, which helps to limit the kind of operations that make sense in each area.

All is ok so far. But then we get to the concept of links. Links that point to other nodes are fine. But the kind of link that says "include link content here" does not make sense in the "content" portion of a node. It's like saying, "include that email thread right *here*" -- that is, to include that hierarchical collection of emails, right in the middle of this paragraph.

No, in a one-node-per-paragraph system, that doesn't make much sense. It would make all kinds of sense to include that thread *underneath*, the current paragraph. But none at all to include it *inside* the current paragraph.

Two Kinds of Pointers

So the conceptual snag is this:

Now, except for "expand the subtree at the current location", the functional behavior of these two kinds of pointers is almost identical. But where a ContainedNode wants to extend StructureNode (adding a ViewControl and type), a LinkNode wants to extend AbstractContentNode (adding the same information, but in a way which does not allow "expand the subtree" as a viewing behavior.

Since the behaviors are so similar, they cry out for a common heritage in the class hierarchy. But since their positions in the hierarchy are so different, they require separate treatment.

Possible Solutions

Some possiblities for resolving the dilemma include:

Overall, that seems like the best solution, internally. (Implementation notes below.) In terms of user functionality, though it means there are two very different kinds of things the user can do:

The operations are very similar, but have very different effects. Will the distinction be clear to users, or will it be confusing?

Implementation Notes

  1. Requires objects that implement it to provide

    ..getType() method

    ..getViewControl() method

    (unfortunately, there is no good way to force the constructors to specify those values, and we need to avoid set() methods to force versioning -- or we could add set() methods and declare by fiat that view control changes and link type changes are not versioned -- TBD)

  2. Implemenation:

    • ContainedNode extends StructureNode implements LinkControl

    • Implementation of reportChange(): NodeLink, changes versionID and stops ContainedNode, changes current versionID and reports change to parents

    • LinkDisplayPolicy:

      ..expand node in place if calling node is an instance of ContainedNode, and policy says to do that

      ..if policy says to expand, and calling node is an instance of Nodelink, show link instead


Eric Armstrong