如何根据符号名称的字符串输入在 Clojure 中创建类型?

How to create a type in Clojure from an input of Strings for symbol names?

我正在尝试创建一个类型列表 - 以便我可以映射一个字符串列表并创建我需要的所有类型。

这是我的目标:

(defprotocol P (methodname [arg1]))

(deftype T [f] P (methodname [arg1] (println "methodname called")))

对于从字符串名称生成类型的单个实例 - 我正在尝试:

(defmacro create-type [type-name field-list protocol-name protocol-sig]
  `(deftype ~type-name ~field-list ~protocol-name ~protocol-sig))

(create-type (symbol "type-name") [field1]  (symbol "P") (methodname [arg1]))

这失败了:

ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol  clojure.core/ns-resolve (core.clj:4026)

我的问题是:如何从符号名称的字符串输入在 Clojure 中创建类型?

有点老套,但对我有用:

(defprotocol P (methodname [arg1]))`

(defmacro gen-type [type-name field-list proto-name proto-sig]
`(load-string (str "(deftype " ~type-name " " ~(str field-list) ~(str proto-name) ~(str proto-sig) ")")))

(gen-type "T" [f1 f2] P (methodname [arg1]))

所以我基本上只是构建一个字符串并使用 reader 对其进行评估。

没有加载字符串(仍然不太灵活,但可以):

(defmacro gentype [t f p m a b]
  `(deftype ~(symbol t) ~f ~p (~m ~a ~b)))

(gentype "T3" [f1 f2] P methodname [arg1] (prn arg1))