Để bắt đầu, tôi đang sử dụng Windows 7 (64 bit), chạy Java phiên bản 6 (cập nhật 33) bằng cách sử dụng clooj làm IDE của tôi. Tôi đã không cố gắng tái tạo vấn đề của mình trong bất kỳ hệ thống nào khác. Tôi có kinh nghiệm với Clojure, nhưng hoàn toàn không có Java.Macro clojure sẽ bảo tồn thứ tự bản đồ liên kết
Toàn bộ vấn đề tôi đang cố gắng giải quyết là dài để mô tả, nhưng nó tóm lại điều này: giả sử tôi muốn tạo macro có một đối số, một bản đồ liên kết và trả về một vectơ các yếu tố của bản đồ với thứ tự được bảo tồn.
=>(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]]
đó làm việc, nhưng thêm một yếu tố khác vào bản đồ và trình tự messes lên ...
=>(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]]
Tôi tin rằng tôi đã khám phá ra lý do tại sao điều này xảy ra. Có vẻ như bất cứ điều gì với 8 hoặc ít hơn các yếu tố được khởi tạo như là một PersistentArrayMap, đó là chính xác những gì tôi muốn, bởi vì từ những gì tôi có thể nói, lớp này giữ lại trật tự. Tuy nhiên, bất kỳ thứ gì có 9 hoặc nhiều phần tử được khởi tạo dưới dạng PersistentHashMap, không giữ lại thứ tự.
=>(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
Tôi muốn macro của mình có thể chụp bản đồ liên kết với mọi kích thước, vì vậy đây là vấn đề. Tôi đã thử loại gợi ý, ràng buộc phá hủy, cho khả năng đọc danh sách và nối kết không cần thiết, tất cả đều không thành công. Để vẽ nó ra, không ai trong số những điều sau đây sẽ làm việc:
(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 [email protected]))
Với vấn đề đồ chơi này tôi trình bày, tôi nhận ra tôi chỉ đơn giản là có thể viết vĩ mô của tôi như vậy, và tránh những vấn đề hoàn toàn:
=>(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]]
Tuy nhiên, đối với vấn đề thực tế Tôi đang cố gắng giải quyết (mà tôi đã không nhận được vào), điều quan trọng (mặc dù không phải 100% cần thiết) mà macro có thể có bản đồ liên kết. Có vẻ như tôi đang tìm cách đưa đối số vào PersistentArrayMap trước khi bất cứ điều gì có cơ hội xảy ra với nó. Có thể có một số cách khác để một giải pháp mà tôi chỉ đơn giản là không xem xét hoặc nhận thức được.
Tôi đã nghiên cứu tốt nhất mà tôi đã biết cách thức và chưa tìm thấy bất kỳ điều gì hữu ích. Có ai có suy nghĩ/lời khuyên nào không?
quy tắc đầu tiên của câu lạc bộ macro là "không viết macro" ... (bạn có thể đoán thứ hai) –
Tôi tưởng tượng quy tắc thứ hai là: "Shut up. Nghiêm túc, đừng viết macro." –