编译 Lambda 表达式时 SBCL 中的微妙编译器警告
Subtle Compiler Warning in SBCL When Compiling a Lambda Expression
我需要一些帮助来理解 SBCL 编译器警告消息,该消息在编译 lambda 表达式时出现。 lambda表达式暂时存储为用户定义名称的符号值,编译后的函数随后存储在该名称的符号函数下。
* (compile nil (symbol-value 'activate-connector-if!))
; in: LAMBDA (STATE ?CONNECTOR)
; (APPLY #'SOME
; (LAMBDA (WOULDWORK-PKG::?T1 WOULDWORK-PKG::?T2)
; (AND
; (GETHASH (+ 126 # #)
; (WOULDWORK-PKG::PROBLEM-STATE.IDB WOULDWORK-PKG::STATE))
; (GETHASH (+ 126 # #)
; (WOULDWORK-PKG::PROBLEM-STATE.IDB WOULDWORK-PKG::STATE))
; (LET (#)
; (WHEN VALUES #))
; (LET (#)
; (WHEN VALUES #))
; (NOT (EQL WOULDWORK-PKG::$HUE1 WOULDWORK-PKG::$HUE2))))
; NIL NIL)
; --> MULTIPLE-VALUE-CALL SB-C::%FUNCALL SOME LET BLOCK SB-INT:DX-FLET FLET
; --> #:WRAPPER102 BLOCK LET
; ==>
; (SB-C::%FUNCALL #:G100 #:G99)
;
; caught WARNING:
; function called with one argument, but wants exactly two
; See also:
; The ANSI Standard, Section 3.2.2.3
;
; compilation unit finished
; caught 1 WARNING condition
#<FUNCTION (LAMBDA (STATE ?CONNECTOR)) {1002E32AAB}>
T
T
警告对应于两个必需的参数,但没有关于从何处调用函数的信息。但是,只有一个可能的地方可以调用它,并且检查验证它是用两个参数调用的。
由于尽管有此警告,程序在所有测试用例上运行良好,起初我认为这意味着该函数从未被调用。但是跟踪验证它使用正确的参数被正确调用了很多次。
是否有任何其他方法可以了解生成警告的原因?
(LAMBDA (WOULDWORK-PKG::?T1 WOULDWORK-PKG::?T2) ...)
需要 2 个参数,但 SOME
只用 1 个参数调用它。当您将 APPLY
调用转换为普通函数调用时,它看起来像:
(some (lambda (?t1 ?t2) ...) '())
需要有与谓词函数的参数一样多的序列参数,但只有一个序列和两个参数。
也许您打算使用 FUNCALL
而不是 APPLY
? APPLY
将其最后一个参数视为参数列表,因此 NIL
没有参数。
我需要一些帮助来理解 SBCL 编译器警告消息,该消息在编译 lambda 表达式时出现。 lambda表达式暂时存储为用户定义名称的符号值,编译后的函数随后存储在该名称的符号函数下。
* (compile nil (symbol-value 'activate-connector-if!))
; in: LAMBDA (STATE ?CONNECTOR)
; (APPLY #'SOME
; (LAMBDA (WOULDWORK-PKG::?T1 WOULDWORK-PKG::?T2)
; (AND
; (GETHASH (+ 126 # #)
; (WOULDWORK-PKG::PROBLEM-STATE.IDB WOULDWORK-PKG::STATE))
; (GETHASH (+ 126 # #)
; (WOULDWORK-PKG::PROBLEM-STATE.IDB WOULDWORK-PKG::STATE))
; (LET (#)
; (WHEN VALUES #))
; (LET (#)
; (WHEN VALUES #))
; (NOT (EQL WOULDWORK-PKG::$HUE1 WOULDWORK-PKG::$HUE2))))
; NIL NIL)
; --> MULTIPLE-VALUE-CALL SB-C::%FUNCALL SOME LET BLOCK SB-INT:DX-FLET FLET
; --> #:WRAPPER102 BLOCK LET
; ==>
; (SB-C::%FUNCALL #:G100 #:G99)
;
; caught WARNING:
; function called with one argument, but wants exactly two
; See also:
; The ANSI Standard, Section 3.2.2.3
;
; compilation unit finished
; caught 1 WARNING condition
#<FUNCTION (LAMBDA (STATE ?CONNECTOR)) {1002E32AAB}>
T
T
警告对应于两个必需的参数,但没有关于从何处调用函数的信息。但是,只有一个可能的地方可以调用它,并且检查验证它是用两个参数调用的。
由于尽管有此警告,程序在所有测试用例上运行良好,起初我认为这意味着该函数从未被调用。但是跟踪验证它使用正确的参数被正确调用了很多次。
是否有任何其他方法可以了解生成警告的原因?
(LAMBDA (WOULDWORK-PKG::?T1 WOULDWORK-PKG::?T2) ...)
需要 2 个参数,但 SOME
只用 1 个参数调用它。当您将 APPLY
调用转换为普通函数调用时,它看起来像:
(some (lambda (?t1 ?t2) ...) '())
需要有与谓词函数的参数一样多的序列参数,但只有一个序列和两个参数。
也许您打算使用 FUNCALL
而不是 APPLY
? APPLY
将其最后一个参数视为参数列表,因此 NIL
没有参数。