Macros 公共Lisp宏参数不匹配,尽管&;休息/&;身体

Macros 公共Lisp宏参数不匹配,尽管&;休息/&;身体,macros,lisp,common-lisp,sbcl,practical-common-lisp,Macros,Lisp,Common Lisp,Sbcl,Practical Common Lisp,我一直在读Peter Seibel的书,按照书中出现的顺序从网上的书代码中拼凑出这个项目,到目前为止,我有一个文件,依次编译和加载每一章的代码,这就是我遇到问题的地方:何时 到目前为止,我为项目加载了FASL,在ID3v2部分中得到了如下警告 我不明白参数编号冲突是从哪里来的UNSIGNED-INTEGER似乎得到了它的两个关键字参数。此外,在我看来,DEFINE-BINARY-TYPE宏将接受任意数量的参数 使用&rest/&body。我想知道你是否有任何提示或建议。下面是一些相关的输出和代码

我一直在读Peter Seibel的书,按照书中出现的顺序从网上的书代码中拼凑出这个项目,到目前为止,我有一个文件,依次编译和加载每一章的代码,这就是我遇到问题的地方:何时 到目前为止,我为项目加载了FASL,在ID3v2部分中得到了如下警告

我不明白参数编号冲突是从哪里来的
UNSIGNED-INTEGER
似乎得到了它的两个关键字参数。此外,在我看来,
DEFINE-BINARY-TYPE
宏将接受任意数量的参数 使用
&rest
/
&body
。我想知道你是否有任何提示或建议。下面是一些相关的输出和代码。 非常感谢您的帮助

提前感谢,

; file: .../cl-playlist/id3v2.lisp
; in: DEFINE-BINARY-TYPE U1
;     (BINARY-DATA:DEFINE-BINARY-TYPE ID3V2::U1
;         NIL
;       (ID3V2::UNSIGNED-INTEGER :BYTES 1 :BITS-PER-BYTE 8))
; ...
; ==>
;   (BINARY-DATA:READ-VALUE 'ID3V2::UNSIGNED-INTEGER #:STREAM :BYTES 1
;                           :BITS-PER-BYTE 8)
; 
; caught STYLE-WARNING:
;   The function was called with six arguments, but wants exactly two.
“id3v2.lisp”中有问题的函数如下所示

(define-binary-type u1 () (unsigned-integer :bytes 1 :bits-per-byte 8))
使用

从“binary data.lisp”中的以下内容


代码存在的问题是调用的函数参数数量错误。该函数是使用较少元素的参数列表创建的

见此:

CL-USER> (defmethod foo ((a string) (b string) &key) (list a b))
STYLE-WARNING:
   Implicitly creating new generic function COMMON-LISP-USER::FOO.
#<STANDARD-METHOD FOO (STRING STRING) {1005603C53}>
现在SBCL告诉我们,我们用四个参数调用泛型函数,即使泛型函数只有两个参数

在您的例子中,
U1
的声明描述了一个具有两个参数的函数。
READ-DATA-VALUE
没有关键字参数

现在有几种可能的方法来解决这个问题:

  • 使用
    DEFGENERIC
    使用您真正想要使用的参数列表定义泛型函数
    READ-DATA-VALUE
    ,并确保所有方法都遵循它

  • 在所有方法中放置所有参数。在不使用它们的方法中,将它们声明为可忽略的

  • 允许其他关键字参数,以允许不同的方法具有不同的关键字参数集。最好也在
    DEFGENERIC
    表单中这样做

  • 然后:

    CL-USER>(defmethod foo1((a字符串)(b字符串)&键和允许其他键)
    (名单a(b))
    样式警告:
    隐式创建新的通用函数COMMON-LISP-USER::FOO1。
    #                                                                                                                                             
    CL-USER>(德芬巴兹)(食品巴兹巴兹:k1 10))
    BAR1
    
    您可以看到SBCL不再抱怨,并假定参数是关键字参数

    CL-USER> (defun bar (baz) (foo baz baz :k1 10))
    ; in: DEFUN BAR
    ;     (FOO BAZ BAZ :K1 10)
    ;
    ; caught STYLE-WARNING:
    ;   The function was called with four arguments, but wants exactly two.
    ;
    ; compilation unit finished
    ;   caught 1 STYLE-WARNING condition
    BAR
    CL-USER> 
    
    缺点是Lisp编译器现在假定您可以为这个泛型函数使用任意关键字参数,并且无法告诉您(也不是在编译时)是否传递了错误的关键字参数

    CL-USER> (defmethod foo ((a string) (b string) &key) (list a b))
    STYLE-WARNING:
       Implicitly creating new generic function COMMON-LISP-USER::FOO.
    #<STANDARD-METHOD FOO (STRING STRING) {1005603C53}>
    
    CL-USER> (defun bar (baz) (foo baz baz :k1 10))
    ; in: DEFUN BAR
    ;     (FOO BAZ BAZ :K1 10)
    ;
    ; caught STYLE-WARNING:
    ;   The function was called with four arguments, but wants exactly two.
    ;
    ; compilation unit finished
    ;   caught 1 STYLE-WARNING condition
    BAR
    CL-USER> 
    
    CL-USER> (defmethod foo1 ((a string) (b string) &key &allow-other-keys)
               (list a b))
    STYLE-WARNING:                                                                                                                                                                                   
       Implicitly creating new generic function COMMON-LISP-USER::FOO1.                                                                                                                              
    #<STANDARD-METHOD FOO1 (STRING STRING) {10058AC193}>                                                                                                                                             
    CL-USER> (defun bar1 (baz) (foo1 baz baz :k1 10))
    BAR1