Macro Clojure que conservará a ordem dos mapas associativos

Para prefácio, estou no Windows 7 (64 bits), executando o Java versão 6 (atualização 33) usandoclooj como meu IDE. Eu não tentei reproduzir meu problema em nenhum outro sistema. Eu sou experiente com o Clojure, mas não com o Java.

A totalidade do problema que estou tentando resolver é demorada para descrever, mas tudo se resume a isto: digamos que eu gostaria de fazer uma macro que pega um argumento, um mapa associativo e retorna um vetor dos elementos do mapa com a sua ordem conservada.

=>(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]]

Isso funciona, mas adicione outro elemento ao mapa e a ordem atrapalha ...

=>(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]]

Eu acredito que descobri porque isso está acontecendo. Parece que qualquer coisa com 8 elementos ou menos é instanciada como um PersistentArrayMap, que é exatamente o que eu quero, porque pelo que eu posso dizer, essa classe retém a ordem. No entanto, qualquer coisa com 9 ou mais elementos é instanciado como um PersistentHashMap, que não retém a ordem.

=>(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

Eu gostaria que minha macro pudesse ter mapas associativos de qualquer tamanho, então isso é um problema. Eu tentei tipo insinuando, ligação de desestruturação,para compreensão da lista e splicing unquote, tudo sem sucesso. Para desenhá-lo, nenhum dos itens a seguir 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))

Com este problema de brinquedo que apresento, percebo que poderia simplesmente escrever minha macro dessa forma e evitar o problema completamente:

=>(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]]

No entanto, para oreal problema que estou tentando resolver (o que não entendi), é importante (embora não seja 100% necessário) que a macro consiga obter mapas associativos. Parece que estou procurando como converter o argumento em um PersistentArrayMap antes que qualquer coisa tenha a chance de acontecer com ele. Pode haver algum outro caminho para uma solução que eu simplesmente não esteja considerando ou ciente.

Eu pesquisei o melhor que conheço e ainda não encontrei nada útil. Alguém tem algum pensamento / conselho?

questionAnswers(2)

yourAnswerToTheQuestion