Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用宏创建defrecord方法会得到Don';我不知道如何从clojure.lang.Symbol创建ISeq_Clojure_Macros - Fatal编程技术网

使用宏创建defrecord方法会得到Don';我不知道如何从clojure.lang.Symbol创建ISeq

使用宏创建defrecord方法会得到Don';我不知道如何从clojure.lang.Symbol创建ISeq,clojure,macros,Clojure,Macros,在玩Clojure时,我尝试使用宏为defrecord中的协议创建方法,但遇到了无法理解的类型错误 用这个最小的协议 (defprotocol fooprot (ffoo [_ v]) ) 我想用一个宏来定义这个方法。以下是两个引用不同的非工作尝试: (defmacro mk-m1 [fnname value] `(~fnname [~'_ ~'p] (str ~'p ~value ))) (defmacro mk

在玩Clojure时,我尝试使用宏为
defrecord
中的协议创建方法,但遇到了无法理解的类型错误

用这个最小的协议

(defprotocol fooprot     
  (ffoo [_ v])    
  )    
我想用一个宏来定义这个方法。以下是两个引用不同的非工作尝试:

(defmacro mk-m1    
 [fnname value]    
 `(~fnname [~'_ ~'p]    
    (str ~'p ~value )))    

(defmacro mk-m2    
 [fnname value]    
 (list fnname '[_ p]    
    (list 'str 'p value )))    
展开它们会得到相同的输出(命名空间和列表类型除外)

如果我将该输出复制并粘贴到
defrecord
中,它们都可以工作:(在这个缩小的示例中,这些方法不使用字段(
x
y

现在,当我尝试使用宏来定义方法时,我得到了
IllegalArgumentException不知道如何从以下位置创建ISeq:clojure.lang.Symbol

(defrecord myrec-m1 [x y]         
  fooprot    
  (mk-m1 ffoo "foo")         
)            
; => IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Symbol  clojure.lang.RT.seqFrom (RT.java:505)

(defrecord myrec-m2 [x y]
  fooprot
  (mk-m2 ffoo "foo")
)
; => IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Symbol  clojure.lang.RT.seqFrom (RT.java:505)
。。。这就是我迷路的地方。问题出在哪个
符号上?看着
宏扩展到什么,在我看来是合理的:

(let [ex (macroexpand '(mk-m1 ffoo "foo"))]
  (println ex " : " (type ex))
  (doseq [tmp ex] (println tmp " : " (type tmp))))
; => (ffoo [_ p] (clojure.core/str p foo))  :  clojure.lang.Cons
;    ffoo  :  clojure.lang.Symbol 
;    [_ p]  :  clojure.lang.PersistentVector 
;    (clojure.core/str p foo)  :  clojure.lang.Cons 
;    nil

其中矢量元素也是符号:

(doseq [e (nth (macroexpand '(mk-m1 ffoo "foo"))1)] 
   (println e " : " (type e)))
;=>  _  :  clojure.lang.Symbol                                                                                     
;    p  :  clojure.lang.Symbol
;    nil
我错过了什么?我是否忽略了一些琐碎的事情,或者是否与
defrecord
宏存在一些交互作用

解决方法是让宏创建函数,然后在方法中调用这些生成的函数

(defrecord myrec1 [x y]    
  fooprot    
  (ffoo [this v] (generated-ffoo this v))    
)    

这是可以的,但我想了解这一点。

defrecord
本身就是一个宏,因此不会对其子窗体执行宏扩展。
避免这种情况的一种快速方法是定义自己的
my defrecord
,该方法使用所需的方法impls扩展为
defrecord

defrecord
本身就是一个宏,因此不会对其子窗体执行宏扩展。
避免这种情况的一种快速方法是定义自己的
my defrecord
,该方法使用所需的方法impls扩展为
defrecord

defrecord
本身就是一个宏,因此不会对其子窗体执行宏扩展。
避免这种情况的一种快速方法是定义自己的
my defrecord
,该方法使用所需的方法impls扩展为
defrecord

defrecord
本身就是一个宏,因此不会对其子窗体执行宏扩展。
避免这种情况的一种快速方法是定义自己的
my defrecord
,使用所需的方法impls将其扩展为
defrecord

defrecord本身就是一个宏。宏内部的宏可能很棘手。我想看看全球扩张。def记录本身就是一个宏。宏内部的宏可能很棘手。我想看看全球扩张。def记录本身就是一个宏。宏内部的宏可能很棘手。我想看看全球扩张。def记录本身就是一个宏。宏内部的宏可能很棘手。我会看一下全球扩张。啊,答案就在问题中:我忽略了一些琐碎的事情,并且与
defrecord
宏有交互作用。谢谢。啊,答案就在这个问题上:我忽略了一些琐碎的事情,并且与
defrecord
宏有交互作用。谢谢。啊,答案就在这个问题上:我忽略了一些琐碎的事情,并且与
defrecord
宏有交互作用。谢谢。啊,答案就在这个问题上:我忽略了一些琐碎的事情,并且与
defrecord
宏有交互作用。谢谢
(let [ex (macroexpand '(mk-m2 ffoo "foo"))]
  (println ex " : " (type ex))
  (doseq [tmp ex] 
    (println tmp " : " (type tmp))) )
; => (ffoo [_ p] (str p foo))  :  clojure.lang.PersistentList                                                     
;    ffoo  :  clojure.lang.Symbol
;    [_ p]  :  clojure.lang.PersistentVector
;    (str p foo)  :  clojure.lang.PersistentList
;    nil
(doseq [e (nth (macroexpand '(mk-m1 ffoo "foo"))1)] 
   (println e " : " (type e)))
;=>  _  :  clojure.lang.Symbol                                                                                     
;    p  :  clojure.lang.Symbol
;    nil
(defrecord myrec1 [x y]    
  fooprot    
  (ffoo [this v] (generated-ffoo this v))    
)