Protoboarda breadboard for programming
Protoboard screenshot

This project was inspired by breadboards: they are used for both learning, and experimenting, allow for very fast iterations, and tap into our spatial reasoning.

Protoboard is a frontend library built on thi.ng/hdom. There's a single exposed function called createBoard which fills the screen with a grid. Pieces of code can be attached to that grid by supplying a name, position, size, and a function:

import createBoard from "protoboard";

const board = createBoard();
board.start();

board.add("hello world", [0, 0], [2, 2], () => {
  return ["h1", "hello!"];
});

Nodes on the board can hold internal state, which other nodes can react to, forming a computational DAG:

board.add("count every second", [0, 0], [2, 2] (state) => ({
  init: () => {
    // initialize with 0
    if (state.deref() === undefined) {
      state.reset(0);
    }

    handle = setInterval(() => {
      state.swap(count => count + 1);
    }, 1000);
  },

  render: () => {
    return ["div", `counter value: ${state.deref()}`];
  },

  release: () => {
    clearInterval(handle);
  }
}));

board.add("counter times two", [2, 0], [2, 2], ({ nodes }) => {
  return ["div", nodes["count every second"] * 2]
});

Protoboard nodes by design encapsulate code instead of other nodes, compared to some VPLs where even basic math equations have to use blocks and connections.

Combination of the background grid, and a quick way to build DOM elements, allows for adding pieces of documentation, notes, and inspiration images inline on the board, creating a canvas for programming:

mini 0
mini 1

Protoboard isn't without issues though. The need to describe position and size of the node in code seems very clean — everything is defined in the same place, and rendering is a pure function over the input file. I just keep on catching myself trying to move the nodes around and resize them using a mouse. Something I want to try is updating the code file when the nodes are moved or resized.

Another issue grows out of the way that nodes are connected together through global naming. This makes it hard to create reusable pieces of code, and the user is forced to create unnecessary abstractions, like:

const createDebugNode = (pos, size, name) => {
  board.add(`${name} debug`, pos, size, ({ nodes }) => {
    return ["code", JSON.stringify(nodes[name], null, 2)];
  });
}
mini 3
mini 2

I believe that writing code in vertical slices on some form of canvas has a lot of benefits, we just don't have the proper interactions and abstractions discovered yet.

  • Protoboard and Liveboard another projects technically from 2019, an answer to a prompt "what if programming was more like using a breadboard"
  • mixing code, visual reference materials, running instances, and data in the same space (I explored some of these ideas in Protoboard)
  • experiments in creating a medium for quick exploratory work: Protoboard

SDFSheets is an experimental spreadsheet interface for working with Signed Distance Functions. It's a continuation of exploring my interests in SDFs (SDF-UI, hiccup-sdf), spreadsheet-like interfaces (Protoboard) and Computational DAGs.