 (def ^:dynamic ^:private *bigdec*)
 (def ^:dynamic ^:private *key-fn*)
 (def ^:dynamic ^:private *value-fn*)
+
+(defn- default-write-key-fn
+  [x]
+  (if (instance? clojure.lang.Named x)
+    (name x)
+    (str x)))
+
+(defn- default-value-fn [k v] v)
 
 (declare -parse)
 

    (.append sb \")
    (.print out (str sb))))

(defn- as-str
  [x]
  (if (instance? clojure.lang.Named x)
    (name x)
    (str x)))

(defn- write-object [m ^PrintWriter out] 
  (.print out \{)
  (loop [x m]
    (when (seq m)
      (let [[k v] (first x)]
        (when (nil? k)
          (throw (Exception. "JSON object keys cannot be nil/null")))
	(write-string (as-str k) out)
        (.print out \:)
        (-write-json v out))
      (let [nxt (next x)]
        (when (seq nxt)
          (.print out \,)

        name (transformed by key-fn) and the value. The return value
        of value-fn will replace the value in the output. If value-fn
        returns itself, the property will be omitted from the output.
        The default value-fn returns the value unchanged."
  [reader & options]
  (let [{:keys [eof-error? eof-value bigdec key-fn value-fn]
         :or {bigdec false
              eof-error? true
              key-fn identity
              value-fn default-value-fn}} options]
    (binding [*bigdec* bigdec
              *key-fn* key-fn
              *value-fn* value-fn]
      (-parse reader eof-error? eof-value))))

(defn parse-string
  "Reads one JSON value from input String. Options are the same as for
