Macro de clojure que conservará el orden asociativo del mapa.

Para comenzar, estoy en Windows 7 (64 bits), ejecutando Java versión 6 (actualización 33) usandoclooj como mi IDE. No he intentado reproducir mi problema en ningún otro sistema. Tengo experiencia con Clojure, pero no con Java.

La totalidad del problema que estoy tratando de resolver es largo para describirlo, pero se reduce a esto: digamos que me gustaría crear una macro que tome un argumento, un mapa asociativo y devuelva un vector de los elementos de Mapa con su orden conservado.

=>(defmacro vectorize-a-map
    [associative-map]
    (vec associative-map))
=>#'ns/vectorize-a-map
=>(vectorize-a-map {:a 1 :b 2 :c 3 :d 4 :e 5 :f 6 :g 7 :h 8}
=>[[:a 1] [:b 2] [:c 3] [:d 4] [:e 5] [:f 6] [:g 7] [:h 8]]

Eso funciona, pero agrega otro elemento al mapa y el orden se confunde ...

=>(vectorize-a-map {:a 1 :b 2 :c 3 :d 4 :e 5 :f 6 :g 7 :h 8 :i 9}
=>[[:a 1] [:c 3] [:b 2] [:f 6] [:g 7] [:d 4] [:e 5] [:i 9] [:h 8]]

Creo que he descubierto por qué sucede esto. Parece que cualquier cosa con 8 o menos elementos se crea como un PersistentArrayMap, que es exactamente lo que quiero, porque de lo que puedo decir, esta clase mantiene el orden. Sin embargo, cualquier cosa con 9 o más elementos se crea una instancia como un PersistentHashMap, que no conserva el orden.

=>(type {:a 1 :b 2 :c 3 :d 4 :e 5 :f 6 :g 7 :h 8}
=>clojure.lang.PersistentArrayMap
=>(type {:a 1 :b 2 :c 3 :d 4 :e 5 :f 6 :g 7 :h 8 :i 9}
=>clojure.lang.PersistentHashMap

Me gustaría que mi macro pudiera tomar mapas asociativos de cualquier tamaño, por lo que este es un problema. He intentado insinuación tipo, desestructuración de enlace,para Enumere la comprensión y el empalme entre comillas, todo sin éxito. Para dibujarlo, nada de lo siguiente funcionará:

(defmacro vectorize-a-map
  [^clojure.lang.PersistentArrayMap associative-map]
  (vec associative-map))

(defmacro vectorize-a-map
  [[& associative-map]]
  (vec associative-map))

(defmacro vectorize-a-map
  [associative-map]
  (vec
    (for [x associative-map]
      x)))

(defmacro vectorize-a-map
  [associative-map]
  `(vector ~@associative-map))

Con este problema de juguete que presento, me doy cuenta de que simplemente podría escribir mi macro así y evitar el problema por completo:

=>(defmacro vectorize-kvs
    [& elements]
    (vec (map vec (partition 2 elements))))
=>#'ns/vectorize-kvs
=>(vectorize-kvs :a 1 :b 2 :c 3 :d 4 :e 5 :f 6 :g 7 :h 8 :i 9)
=>[[:a 1] [:b 2] [:c 3] [:d 4] [:e 5] [:f 6] [:g 7] [:h 8] [:i 9]]

Sin embargo, para elreal El problema que estoy tratando de resolver (en el que no me he metido), es importante (aunque no es 100% necesario) que la macro pueda tomar mapas asociativos. Parece que estoy buscando la forma de convertir el argumento en un PersistentArrayMap antes de que algo tenga la oportunidad de pasarle. Puede haber algún otro camino hacia una solución que simplemente no estoy considerando o no conozco.

He investigado lo mejor que he conocido y aún no he encontrado nada útil. ¿Alguien tiene algún pensamiento / consejo?

Respuestas a la pregunta(2)

Su respuesta a la pregunta