docs: function S(fn, value) {
      var owner = Owner, clock = RunningClock === null ? RootClock : RunningClock, running = RunningNode;
      if (owner === null)
          console.warn("computations created without a root or parent will never be disposed");
      var node = new ComputationNode(clock, fn, value);
      Owner = RunningNode = node;
      if (RunningClock === null) {
          toplevelComputation(node);
      }
      else {
          node.value = node.fn(node.value);
      }
      if (owner && owner !== UNOWNED) {
          if (owner.owned === null)
              owner.owned = [node];
          else
              owner.owned.push(node);
      }
      Owner = owner;
      RunningNode = running;
      return function computation() {
          if (RunningNode !== null) {
              var rclock = RunningClock, sclock = node.clock;
              while (rclock.depth > sclock.depth + 1)
                  rclock = rclock.parent;
              if (rclock === sclock || rclock.parent === sclock) {
                  if (node.preclocks !== null) {
                      for (var i = 0; i < node.preclocks.count; i++) {
                          var preclock = node.preclocks.clocks[i];
                          updateClock(preclock);
                      }
                  }
                  if (node.age === node.clock.time()) {
                      if (node.state === RUNNING)
                          throw new Error("circular dependency");
                      else
                          updateNode(node); // checks for state === STALE internally, so don't need to check here
                  }
                  if (node.preclocks !== null) {
                      for (var i = 0; i < node.preclocks.count; i++) {
                          var preclock = node.preclocks.clocks[i];
                          if (rclock === sclock)
                              logNodePreClock(preclock, RunningNode);
                          else
                              logClockPreClock(preclock, rclock, RunningNode);
                      }
                  }
              }
              else {
                  if (rclock.depth > sclock.depth)
                      rclock = rclock.parent;
                  while (sclock.depth > rclock.depth + 1)
                      sclock = sclock.parent;
                  if (sclock.parent === rclock) {
                      logNodePreClock(sclock, RunningNode);
                  }
                  else {
                      if (sclock.depth > rclock.depth)
                          sclock = sclock.parent;
                      while (rclock.parent !== sclock.parent)
                          rclock = rclock.parent, sclock = sclock.parent;
                      logClockPreClock(sclock, rclock, RunningNode);
                  }
                  updateClock(sclock);
              }
              logComputationRead(node, RunningNode);
          }
          return node.value;
      };
  }