ryoakg
12/5/2016 - 10:39 AM

generate-a-map-literal-by-defmacro.clj

(defmacro generate-map-literal []
  `{~@[:a 1]})
;;; clojure.lang.LispReader$ReaderException: java.lang.RuntimeException: Map literal must contain an even number of forms
;;;              java.lang.RuntimeException: Map literal must contain an even number of forms
;;; clojure.lang.LispReader$ReaderException: java.lang.RuntimeException: Unmatched delimiter: )
;;;              java.lang.RuntimeException: Unmatched delimiter: )
;;; 2つで偶数のハズなのになぁ???


;;; もちろん同じ様にしてベクタを作るのは問題ない
(defmacro generate-vector-literal []
  `[~@[:a 1]])
(generate-vector-literal)
;; => [:a 1]


;;; 関数で作れば問題ないけど、何度も実行されそうなのが嫌!!!
(defmacro generate-map []
  `(array-map ~@[:a 1]))
(generate-map)
;; => {:a 1}


(defmacro generate-map-literal2 []
  `{~@[:a 1] ~@[]})
(generate-map-literal2)
;; => {:a 1}



(defmacro generate-map-literal3 [xs]
  `{~@xs ~@[]})
(generate-map-literal3 [:a 1 :b 2])
;; => {:b 2, :a 1}
;;; できた!!


;;; もちろんコレはダメ
(generate-map-literal3 [:a 1 :b])
;;; java.lang.IllegalArgumentException: No value supplied for key: :b
;;;
;;; 最初の generate-map-literal は defmacro の時点でエラーだったけど
;;; こっちは、マクロを展開する時点でエラー
;;;
;;; http://stackoverflow.com/questions/32078605/clojure-generating-a-vector-vs-a-map-literal-expression