           "even?" ["x-1"] (pipe-ref "even?")
           "result" ["even?"] (cljs-ref not))})
 
-(defn run-example [example inputs]
+(def example-d
+  #{(pipe "root" ["x"]
+          "c" ["x"] (match (data-map (data-value "counter") (bind "c" any)) ["c"] return)
+          "one" [] (data-value 1)
+          "c+1" ["c" "one"] (cljs-ref +)
+          "nil" ["c" "c+1"] replace)})
+
+(defn run-example [example input]
   (let [stack #js []
-        program (into {} (for [pipe example] [(:id pipe) pipe]))]
+        program (into {} (for [pipe example] [(:id pipe) pipe]))
+        output (atom input)]
     (try
-      [(run-pipe program (get program "root") (map #(Cursor. [] %) inputs) stack) (aget stack 0)]
-      (catch :default e [e (aget stack 0)]))))
-
-(set! *print-meta* true)
-
-(run-example example-a [1 4 2])
-
-(run-example example-b [{"a" 1 "b" 2}])
-(run-example example-b [{"a" 1 "c" 2}])
-(run-example example-b [{"a" 1 "b" "foo"}])
-(run-example example-b [[1 "foo"]])
-(run-example example-b [[1 2]])
-
-(run-example example-c [0])
-(run-example example-c [1])
-(run-example example-c [7])
-(run-example example-c [10])
+      [(run-pipe program (get program "root") [(Cursor. [] input)] output stack) @output (aget stack 0)]
+      (catch :default e [e @output (aget stack 0)]))))
+
+(run-example example-b {"a" 1 "b" 2})
+(run-example example-b {"a" 1 "c" 2})
+(run-example example-b {"a" 1 "b" "foo"})
+(run-example example-b [1 "foo"])
+(run-example example-b [1 2])
+
+(run-example example-c 0)
+(run-example example-c 1)
+(run-example example-c 7)
+(run-example example-c 10)
+
+(run-example example-d {"counter" 0})
 
 (defn print-stack
   ([frame]

(def any
  {:type :match/any})

;; examples

(def example-a

(ns aurora.interpreter)

;; todo

;; efficient implementation of stack queries (maybe only compile the watched fn?)
;; efficient implementation of cursors (maybe via side-vars)

;; interpreter

(defrecord Cursor [path value])

(defn run-pipe [program node inputs output stack]
  (let [vars #js {}
        calls #js []
        frame #js {:id (:id node) :vars vars :calls calls}]
