lisp - 我可以将 lambda 与即时 lambda 列表(没有宏)一起使用吗?

标签 lisp common-lisp sbcl

我正在尝试创建一个函数来返回函数,其中包含动态生成的任意 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变成一个函数,你需要替换 functioncompile或者 (coerce (lambda ...) 'function) .

但是,您的重构被误导了。 make-canned-format 应该是一个宏——这样它会产生 current compilation environment 中的闭包. 然而,该函数将在 global environment 中产生一个闭包。 .

关于lisp - 我可以将 lambda 与即时 lambda 列表(没有宏)一起使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52338570/

相关文章:

lisp - Common Lisp 中的列表和成员实现

java - Java 是否支持像 Lisp 那样基于多个对象的类型分派(dispatch)到特定的实现?

javascript - 如何将此 JavaScript 代码片段翻译成 Parenscript?

macros - 如何在 sbcl common lisp 中的 let 绑定(bind)中定义(defmacro)宏?

common-lisp - 忽略结果时,MAPCAR、MAPC 和 MAP 是否编译为类似的代码?

lisp - CentOS 7 上的 Common Lisp

list - 如何在 LISP 中使用循环

lisp - Elixir 和 Julia 之类的语言在什么意义上是同音的?

list - common lisp 自定义比较函数

performance - 用于性能的 defclass 类型信息