 (defmethod emit* :meta
   [{:keys [expr meta env]}]
   (emit-wrap env
-    (emits "with_meta(" expr "," meta ")")))
+    (emits "With_meta(" expr "," meta ")")))
+
+(def ^:private array-map-threshold 8)
+(def ^:private obj-map-threshold 8)
+
+(defn distinct-keys? [keys]
+  (and (every? #(= (:op %) :constant) keys)
+       (= (count (into #{} keys)) (count keys))))
 
 (defmethod emit* :map
   [{:keys [env keys vals]}]

      (io/file (to-path (cons target parents)))
      (str (last relative-path) ".go"))))


;; TODO: needs fixing, table will include other things than keywords - David


(defn go-public [s]
  (str (string/upper-case (subs (name s) 0 1)) (subs (name s) 1)))

(defn- comma-sep [xs]
  (interpose "," xs))

(defn- escape-char [^Character c]
  (let [cp (.hashCode c)]
    (case cp
      ; Handle printable escapes before ASCII
      34 "\\\""
      92 "\\\\"
      ; Handle non-printable escapes
      8 "\\b"
      12 "\\f"
      10 "\\n"
      13 "\\r"
      9 "\\t"
      (if (< 31 cp 127)
        c ; Print simple ASCII characters
        (format "\\u%04X" cp))))) ; Any other character is Unicode

(defn- escape-string [^CharSequence s]
  (let [sb (StringBuilder. (count s))]
    (doseq [c s]
      (.append sb (escape-char c)))
    (.toString sb)))

(defn- wrap-in-double-quotes [x]
  (str \" x \"))

(defmulti emit* :op)

(defn emit [ast]
  (env/ensure
    (when *source-map-data*
      (let [{:keys [env]} ast]
        (when (:line env)
          (let [{:keys [line column]} env]
            (swap! *source-map-data*
              (fn [m]
                (let [minfo (cond-> {:gcol (:gen-col m)
                                     :gline (:gen-line m)}
                              (= (:op ast) :var)
                              (assoc :name (str (-> ast :info :name))))]
                  ; Dec the line/column numbers for 0-indexing.
                  ; tools.reader uses 1-indexed sources, chrome
                  ; expects 0-indexed source maps.
                  (update-in m [:source-map (dec line)]
                    (fnil (fn [line]
                            (update-in line [(if column (dec column) 0)]
                              (fnil (fn [column] (conj column minfo)) [])))
                      (sorted-map))))))))))
    (emit* ast)))

(defn emits [& xs]
  (doseq [x xs]
    (cond
     (nil? x) nil
     (map? x) (emit x)
     (seq? x) (apply emits x)
     (fn? x)  (x)
     :else (let [s (print-str x)]
             (when *source-map-data*
               (swap! *source-map-data*
                 update-in [:gen-col] #(+ % (count s))))
             (print s))))
  nil)

(defn emitln [& xs]
  (when-let [line (and *go-line-numbers* (some (comp :line :env) xs))]
