How can I programmatically generate record definitions?

tsleyson

In my answer to a Code Review.SE question, I suggested that the OP might consider using records to represent chess pieces. Since the piece records would all be the same, except for the name, I figured I could generate them programmatically, like this:

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

That sort of worked, but my record names weren't the piece names; they were random gensyms: instead of user.Rook I got user.p1__910. If I did (p1__910. :black), it did work and create a record, but you can probably see why I wasn't satisfied with that.

I also tried the following two variations:

(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's wrong with my approach? How can I generate a bunch of identical records from a list of names? Is this even possible?

Arthur Ulfeldt

This is a classic case of macro-contagion.

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

You where very close with the (symbol %) idea you just needed to make it so the defrecord expressions generated are evaluated after you provide the values.

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

How to generate new web page programmatically

来自分类Dev

What are bag attributes and how can i generate them?

来自分类Dev

How can programmatically configure the @ComponentScan?

来自分类Dev

How can I find out how much physical space a record (BLOB) in a sqlite database uses?

来自分类Dev

Where can I get or generate appkey.c for Spotify?

来自分类Dev

How do I programmatically disable Hazelcast client's logging?

来自分类Dev

How can we skip a record while looping through an array in ReactJS

来自分类Dev

How do I get the matching id for every record?

来自分类Dev

How can I cancel an ngEvent?

来自分类Dev

How can I return a function?

来自分类Dev

Can parameters from a parametrized class be used in external function definitions?

来自分类Dev

How can I create a histogram in R?

来自分类Dev

How can I select with column of lists

来自分类Dev

How can I extract text from images?

来自分类Dev

How can I pipe input to a process?

来自分类Dev

How i can onUpgrade me database in Android

来自分类Dev

How can I check for reference equality in Perl?

来自分类Dev

How can I use the constraints in native webrtc?

来自分类Dev

How can I get the application path in C?

来自分类Dev

How can I have mocha reporter for protractor?

来自分类Dev

How can I create this complicated SQL query?

来自分类Dev

How can I highlight a line in TMemo?

来自分类Dev

How can I archive old git tags?

来自分类Dev

How can I limit the results in a PagingAndSortingRepository @Query?

来自分类Dev

How can I search a range of lines in python?

来自分类Dev

How can I debug a custom transformer

来自分类Dev

How can I sort related entities in Ebean?

来自分类Dev

How can I prepend to an array in Ruby?

来自分类Dev

how can I change forecolor of a chart label?

Related 相关文章

热门标签

归档