我可以将lambda与动态lambda列表一起使用(不带宏)吗? [英] Can I use lambda with an on-the-fly lambda list (without macros)?

查看:122
本文介绍了我可以将lambda与动态lambda列表一起使用(不带宏)吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个函数以返回具有即时生成的任意lambda列表的函数.我可以使用宏来做到这一点,但是我正尝试去宏观化我已经拥有的东西:

I'm trying to create a function to return functions, with arbitrary lambda lists, generated on the fly. I can do it with macros, but I'm trying to de-macro-ify what I've already got:

(defmacro make-canned-format-macro (template field-names)
  `(function (lambda ,field-names
               (apply #'format `(nil ,,template ,,@field-names)))))

我可以按如下方式使用它:

I can use it as follows:

* (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).)我正在尝试执行适当的Lisp重构,并删除了不必为宏的宏.但是,我一直试图将任意的lambda列表合并到要在函数中执行的lambda中:

This is exactly the behavior I want. It returns a function whose lambda list was supplied on the fly (in this case, (fuel device).) I'm trying to do the Proper Lisp Refactoring Thing and do away with macros that don't have to be macros. However, I've gotten stuck trying to glom an arbitrary lambda list into a lambda that's getting executed in a function:

* (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之外,它的可读性比宏还差.)

Is what I'm trying to do even possible? (Aside from some hideous eval hack that would be way less readable than the macro, I mean.)

推荐答案

要将make-canned-format转换为功能,您需要替换 function compile (coerce (lambda ...) 'function) .

To turn make-canned-format into a function, you need to replace function with compile or (coerce (lambda ...) 'function).

但是,您的重构是错误的. make-canned-format 应该是宏-这样,它将产生 在当前编译环境中关闭. 但是,该函数将在 global 环境中产生一个闭包. .

However, your refactoring is misguided. make-canned-format should be a macro - this way it will produce a closure in the current compilation environment. The function, however, will produce a closure in the global environment.

这篇关于我可以将lambda与动态lambda列表一起使用(不带宏)吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆