はじめに、私は Windows 7 (64 ビット) を使用しており、IDE としてcloojを使用して Java バージョン 6 (アップデート 33) を実行しています。他のシステムで問題を再現しようとはしていません。私は Clojure の経験はありますが、Java の経験はまったくありません。
私が解決しようとしている問題全体を説明すると長くなりますが、要約すると次のようになります。たとえば、1 つの引数、連想マップを取り、その要素のベクトルを返すマクロを作成したいとします。順序が保存されたマップ。
=>(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]]
それは機能しますが、マップに別の要素を追加すると、順序がめちゃくちゃになります...
=>(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]]
なぜこれが起こっているのかを発見したと思います。8 つ以下の要素を持つものはすべて PersistentArrayMap としてインスタンス化されるようです。これはまさに私が望むものです。なぜなら、このクラスは順序を保持しているためです。ただし、9 つ以上の要素を持つものはすべて、順序を保持しない PersistentHashMap としてインスタンス化されます。
=>(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
マクロで任意のサイズの連想マップを取得できるようにしたいのですが、これは問題です。リストの理解のために、タイプヒント、バインディングの分解、および引用符を外してスプライシングを試みましたが、すべて成功しませんでした。それを引き出すには、次のいずれも機能しません。
(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))
私が提示したこのおもちゃの問題では、マクロを次のように書くだけで、問題を完全に回避できることがわかりました。
=>(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]]
しかし、私が解決しようとしている実際の問題 (これには触れていません) では、マクロが連想マップを取得できることが重要です (ただし、100% 必要というわけではありません)。何かが起こる前に引数を PersistentArrayMap にキャストする方法を探しているようです。私が単に考えていない、または認識していない解決策への道が他にあるかもしれません。
私が知っている最善の方法で調査しましたが、まだ役立つものは何も見つかりませんでした. 誰か考えやアドバイスはありますか?