我正在尝试创建一个函数来返回函数,其中包含动态生成的任意 lambda 列表。我可以用宏来做到这一点,但我正在尝试去宏化我已经拥有的东西:
(defmacro make-canned-format-macro (template field-names)
`(function (lambda ,field-names
(apply #'format `(nil ,,template ,,@field-names)))))
我可以按如下方式使用它:
* (make-canned-format-macro "~A-powered ~A" (fuel device))
#<FUNCTION (LAMBDA (FUEL DEVICE)) {10067D975B}>
* (setf (fdefinition 'zoom-zoom) (make-canned-format-macro "~A-powered ~A" (fuel device)))
#<FUNCTION (LAMBDA (FUEL DEVICE)) {1006835A5B}>
* (zoom-zoom "nuclear" "pogo stick")
"nuclear-powered pogo stick"
这正是我想要的行为。它返回一个函数,其 lambda 列表是动态提供的(在本例中为 (fuel device)
。)必须是宏。但是,我一直在尝试将任意 lambda 列表 glom 到一个在函数中执行的 lambda
中:
* (defun make-canned-format (template field-names)
#'(lambda field-names (apply #'format `(nil ,template ,@field-names))))
; in: DEFUN MAKE-CANNED-FORMAT
; #'(LAMBDA FIELD-NAMES (APPLY #'FORMAT `(NIL ,TEMPLATE ,@FIELD-NAMES)))
;
; caught ERROR:
; The lambda expression has a missing or non-list lambda list:
; (LAMBDA FIELD-NAMES (APPLY #'FORMAT `(NIL ,TEMPLATE ,@FIELD-NAMES)))
; (SB-INT:NAMED-LAMBDA MAKE-CANNED-FORMAT
; (TEMPLATE FIELD-NAMES)
; (BLOCK MAKE-CANNED-FORMAT
; #'(LAMBDA FIELD-NAMES (APPLY #'FORMAT `(NIL ,TEMPLATE ,@FIELD-NAMES)))))
;
; caught STYLE-WARNING:
; The variable TEMPLATE is defined but never used.
;
; caught STYLE-WARNING:
; The variable FIELD-NAMES is defined but never used.
;
; compilation unit finished
; caught 1 ERROR condition
; caught 2 STYLE-WARNING conditions
MAKE-CANNED-FORMAT
我正在尝试做的事情是否可行? (除了一些可怕的 eval
hack 之外,我的意思是,它的可读性不如宏。)
最佳答案
要将make-canned-format
变成一个函数,你需要替换
function
和
compile
或者
(coerce (lambda ...) 'function)
.
但是,您的重构被误导了。
make-canned-format
应该是一个宏——这样它会产生
current compilation environment 中的闭包.
然而,该函数将在 global environment 中产生一个闭包。 .
关于lisp - 我可以将 lambda 与即时 lambda 列表(没有宏)一起使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52338570/