How can I programmatically generate record definitions?

In response to a Code Review.SE question, I suggested that the OP could use notes to represent chess pieces. Since the fragment records will be the same, except for the name, I decided that I could generate them programmatically, for example:

(map #(defrecord % [color]) 
      ["Rook" "Pawn" "Queen" "King" "Knight" "Bishop"])

Such a job, but my record names were not piece names; they were random gensyms: instead user.RookI received user.p1__910. If I did (p1__910. :black), it worked and created the record, but you can probably understand why I was not happy with it.

I also tried the following two options:

(map #(defrecord % [color]) 
      ['Rook 'Pawn 'Queen 'King 'Knight 'Bishop])
  ;; Same result as above.
(map #(defrecord (symbol %) [color])
           ["Rook" "Knight" "Pawn" "Queen" "King" "Bishop"])
  ;; CompilerException java.lang.ClassCastException: clojure.lang.PersistentList 
  ;; cannot be cast to clojure.lang.Symbol, compiling:(NO_SOURCE_PATH:1:7) 

What is wrong with my approach? How can I generate a bunch of identical entries from a list of names? Is it possible?

+4
2

.

user> defrecord
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/defrecord, compiling:(/tmp/form-init802461651064926183.clj:1:5990) 

, (symbol %), , defrecord .

user> (defmacro make-pieces [piece-names]
        `(do ~@(map #(list 'defrecord (symbol %) '[color]) 
                    piece-names)))
#'user/make-pieces

user> (macroexpand-1 '(make-pieces ["Rook" "Pawn" "Queen" "King" "Knight" "Bishop"]))
(do (defrecord Rook [color]) 
    (defrecord Pawn [color]) 
    (defrecord Queen [color]) 
    (defrecord King [color]) 
    (defrecord Knight [color]) 
    (defrecord Bishop [color]))

user> (make-pieces ["Rook" "Pawn" "Queen" "King" "Knight" "Bishop"])
user.Bishop
+5

, ? :

(defrecord Chess-Piece [name color])

, , defrecord , "name" . .

% gensym (p1__910), , , , .

, , - , (defrecord some-symbol [color]) ( , ), some-symbol - , . , - :

(defmacro defpieces [names]
  (let [defs (map #(list 'defrecord (symbol %) '[color])
                  names)]
    `(do ~@defs)))

:

(map #(defrecord % [color]) 
  ["Rook" "Pawn" "Queen" "King" "Knight" "Bishop"])

():

(map (fn* [p1__910#] (defrecord p1__910# [color])
  ["Rook" "Pawn" "Queen" "King" "Knight" "Bishop"])

defrecord , ( , ) , :

(deftype* p1__910# user.p1__910# .....

, macroexpand:

(macroexpand '(defrecord p1__910# [color]))
+5

All Articles