 (defn context
   "Look up a context. If no context exists, create one."
   [id]
-  (or (@contexts id)
-      (get
-       (swap! contexts assoc id
-              {:results []
-               :count 0
-               :stdout []
-               :stderr []})
-       id)))
+  (let [id (str id)]
+    (or (@contexts id)
+        (get
+         (swap! contexts assoc id
+                {:results {}
+                 :eval 0
+                 :result 0
+                 :callbacks {}
+                 :stdout []
+                 :stderr []})
+         id))))
 
 (defn update-context
   "Update a context."
   [id key f & args]
-  (context id)
-  (swap! contexts update-in [id key] (fn [old] (apply f old args))))
+  (let [id (str id)]
+    (context id)
+    (get-in
+     (swap! contexts update-in [id key] (fn [old] (apply f old args)))
+     [id key])))
 
 (defn netstring
   "Create a netstring."

    (cond (#{:stdout :stderr} type)
          (update-context id type conj content)
          (#{:result :error :read-error} type)
          (update-context id :results conj [type content]))
    (prn data)))

(defn connect
  ([port] (connect port "localhost"))
  ([port host]
     (let [sock (.createConnection net port host)]
       (.on sock "data" on-data))))

(defn -main [& args]
  (let [sock (connect 1337 "localhost")]
    (eval sock "(range 1000)")
    (eval sock "(+ 5 5)")))

(set! *main-cli-fn* -main)

(defn eval
  "Evaluate code."
  ([sock form callback] (eval sock form (rand-int 9999999999999999) callback))
  ([sock form id callback]
     (send-message sock id "eval" form)
     (update-context id :callbacks assoc
                     (update-context id :eval inc)
                     callback)))

(defn tail
  "Tail stdout or stderr from a context."
