docs: function registerReactor(forms) {
    if (forms.length != 5)  {
      forms.error('#react expects: before/after, fnname, (observed cells), reactorcode');
    }
  
    // the word "before" or "after"
    var when = sl.valueOf(forms[1]);
    // a list of functions e.g. (set, ++, --)
    var cmds = forms[2];
    // a list of cells (arguments to the "cmds")
    var observed = forms[3];
    // code to inject when these cmds are invoked on these cells
    var reactorcode = this.transpileExpression(forms[4]);
  // THIS DEBUG STATEMENT IS DUMPING THE WHOLE FORMS NEED TO PRETTY IT UP TO JUST THE NAMES
    debug('registering code to be run ' + when + ' one of "' + cmds + ' invoked on "' + observed + '"');
  
    // observed are the variables they need to declare as #cell
    // note: #cell is only done to encourage them to think of these
    //   variables as global to the file since we have no way to distinguish
    //   a reference to a variable in one scope from a variable with the same
    //   name in another (since we're a transpiler not an interpreter)
    var source = sl.lexerOf(forms);
    observed.forEach(function(cell) {
      var arg = sl.valueOf(cell);
      if(source.cells.indexOf(arg) === -1) {
        console.log('warning: reactor function observes "' + arg +
                      '" but "' + arg + '" is not a cell');
      }
    });
  
    // we store for each "cmd" an array of objects of the form:
    //   { of: [observed1, ..., observedN], insert: form }
    // where "observed" are first args for cmd (e.g. "(set observedX val)"), and
    // insert is the (already generated) js code to insert before/after
    cmds.forEach(function(cmdAtom) {
      var cmdName = sl.valueOf(cmdAtom);
      if(!source.bindingCode[when][cmdName]) {
        source.bindingCode[when][cmdName] = [];
      }
      source.bindingCode[when][cmdName].push({of: observed, insert: reactorcode});
    });
  
    // we expand to nothing our only job is to register the
    // code that the main transpiler injects when appropriate
    this.noSemiColon = true;
    return sl.generated();
  }