Raymond Finzel


Adventures in a Different Computer Universe

Part 1 - What's the idea here?

The great Ted Nelson, now a ripe 80 years old, has spent the better part of 60 years detailing a new and exciting computer universe. He's managed teams, written books, and published papers about the technical details, overall feel, goals of the project, and the obstacles that blocked the path to implementation. He's written and spoken at length about the political and artistic decisions that have made computers and technology what they are today. I won't rehash too much of what he's said – there are much more reliable sources than me, and many of the ideas are available straight from the horse's mouth, so to speak. If you're interested in Ted's life story, general attitude, and understanding, I'd recommend his recent video Here I Stand, at Age 80, and his series Computers for Cynics. Further reading of his autobiography, Possiplex, and other miscellany is also highly recommended.

The aspects of his work that I'll be exploring now are detailed explicitly in a few papers. There's Xanalogical Structure, Needed Now More Than Ever, Ted Nelson's Phd thesis Philosophy of Hypertext, and the main design document for this series – the titular paper – Cosmology for a Different Computer Universe.

Ted's computer universe does not hide the interconnected nature of knowledge. It blurs the lines between source and substance as references, transpointing windows, visible links, and infinite versioning collide. Books (and blogs) become a little less fake, and writing becomes a task of harnessing the infinite, rather than wending a narrow path through a wide reality.

This is a big vision, and I'm not even going to begin to touch all of it in one blog post. What I'm going to do instead is implement just one small part: zzstructure. No views, no IO, nothing like that yet. Just going to get warmed up, get my toes wet, and make something that will be useful later.


I have several big hurdles to overcome in order to commence this project:

  1. I'm not very smart
  2. I have no idea what I'm doing

Since Ted Nelson's original vision for a zzstructured universe wishes for a program that lays alongside the operating system, I'll need to do some systems programming. I do not usually do systems programming. Fuck it. Let's try Rust. I've heard good things – and maybe it'll stop me from breaking as much stuff as I would trying to write safe code in C. Another time.

Of course, all bets are off as soon as I start using unsafe methods from the nightly builds in order to make Rust more pythonic so that I can wrap my tiny brain around it.

Anyway. Let's state some expectations, starting with the ones I'll be implementing right now.

  1. zzstructured datatypes
    1. cells
    2. links (implicit and anonymous)
    3. dimensions (axes upon which links are established)
    4. topology (contains the entire structure)
  2. utility functions for dealing with cells and links
    1. iterate over the space
    2. insert "posward" in a dimension
    3. insert "negward" in a dimension
    4. delete cell and update neighbors
    5. update cell contents
  3. engine to "run" cells if that is their purpose
  4. way to serialize the entire topology to disk
  5. socket connection to data backend so that any UI can be generalized

I'm going to call this project "Slumberland" after the ill fated anime Little Nemo: Adventures in Slumberland that was a staple of my childhood, and as a nod to the utopian pantheon that Ted Nelson established as the basis for his work on hypertext systems.

Part 2 - Rusty Beginnings

Items 1 and 2 seem like one discrete task that I can work on.

First things first, Ted Nelson's zzstructure (despite any objections) is essentially, from an implementation standpoint, "doubly linked lists in n-dimensions," where any cell can be part of any list in any dimension at any time, but cells cannot exist more than once in a single dimension.

Ted views this zzstructure as a generalization of spreadsheets, and I happen to agree with him. We've got a) dimensions as a semantic space, b) cells for content, and c) linearizability for comprehension.

Regardless of what zzstructure is, building doubly-linked lists in Rust is Non-Trivialâ„¢, because of single ownership (a concept that keeps Rust memory-safe). Cells or nodes owning a "posward" cell and that "posward" cell owning the original cell right back via the "negward" link is #problematic.

Here's some Rust-y pseudocode. If Rust were an interpreted language, we'd be done. It's not, so we're not. Also, ugh, I picked "cell" as one of these datatype's name. There's a std::cell::*, but please don't get mad. Maybe I'll change it in future versions.

pub enum CellType {
    Value(String), // Text, Numeral, File, Image, etc.
    Function(String), // Transforms previous cell with code
    Monad(String), // Performs some cell-independent function ("side-effects")
    Vertex // Holds a place in a topology without representing data
    // More?
}

pub struct Cell {
    posward: HashMap<Dimension, Cell>, // Links to posward cells
    negward: HashMap<Dimension, Cell>, // Links to negward cells
    content: CellType // what's in the cell!?
}

pub struct Dimension(String); // dimension can literally just be a String

pub struct Topology {
    d_cursor: Dimension, // which dimension always links to the accursed cell?
    accursed: Cell, // that first cell
    dimensions: Vec<Dimension> // list(Vec) of all dimensions in the topology
}

Let's use a Rust-y pattern to give us shared references to those attributes instead. There's std::ptr::Shared, but that's still experimental. The classic way to do it is with Reference Counted pointers and Reference Cells. You can learn about why here. Basically, though, we can pass around references and then borrow the data when we need to interact with it. Here are our datatypes now. I've added some derived traits for ease of use.

#[derive(Clone, Debug)]
pub enum CellType {
    Value(String),
    Function(String),
    Monad(String),
    Vertex
}

#[derive(Clone, Debug)]
pub struct Cell {
    posward: Option<HashMap<Dimension, Rc<RefCell<Cell>>>>,
    negward: Option<HashMap<Dimension, Rc<RefCell<Cell>>>>,
    content: CellType
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Dimension(String);

pub struct Topology {
    d_cursor: Dimension,
    accursed: Rc<RefCell<Cell>>,
    dimensions: Vec<Dimension>
}

These are better! Done? Probably not, but they work! I've implemented a few of the utility functions I mentioned above to confirm that I can build and move around a zzstructured data structure. Much of the design was informed by the source code for the new LinkedList collection type in the standard library. Everything had to be generalized into n dimensions, and I probably sacrificed on speed and efficiency to maintain safety. Keep in mind that this project is evolving continuously and names / implementations are unlikely to stick around for long. Also: I'm new to Rust, so I'll take suggestions.

Part 3 - What does that get us?

Well, very little. I have a data structure. It was convoluted enough that despite my best efforts I understand pointers now, and I understand more of Rust. Next I'll have to serialize the datastructure to and from disk, so that a workspace can become "permanent". I really can't wait. This is an exciting project with exciting implications. Nelson's focus on mental constructs and how to represent them on the computer will never cease to intrigue and delight.

I just hope that as I implement features the Rust can get Rustier and the structure can get Nelsonier along the way.


All code on this page is GPL v3, as per the license in my git repository