              ~'?__bindings__ (atom ~initial-bindings)]
          (do ~@(compile-constraints constraints (set binding-keys)))))))
 
-(defn compile-action [binding-keys rhs]
+(defn compile-action
+  "Compile the right-hand-side action of a rule, returning a function to execute it."
+  [binding-keys rhs]
   (let [assignments (mapcat #(list (symbol (name %)) (list 'get-in '?__token__ [:bindings %])) binding-keys)]
     `(fn [~'?__token__] 
        (let [~@assignments]

  (right-activate [node join-bindings elements memory transport])
  (right-retract [node join-bindings elements memory transport]))

;; Right 
(defprotocol IAccumRightActivate
  ;; Pre-reduces elements, returning a map of bindings to reduced elements.
  (pre-reduce [node elements])


  (description [node] "ProductionNode"))

;; The QueryNode is a terminal node that stores the
;; state that can be queried by a rule user.
(defrecord QueryNode [id query param-keys]
  ILeftActivate  
  (left-activate [node join-bindings tokens memory transport] 
