如何将 lambda 传递给宏?
How to pass lambda to macro?
我需要传递函数并使用指定的参数调用它。如何正确地将 lambda 函数传递给宏并避免此错误:
APPLY: #'(LAMBDA (X) (+ X 1)) is not a function name; try using a symbol instead
代码:
(defmacro runner (fun &rest arg)
(apply fun arg))
通话:
(runner #'(lambda (x) (+ x 1)) '(1))
我的代码有什么问题?用 +
函数尝试了类似的东西,一切正常。
更新:
程序应该为每个参数和 return 结果调用指定的函数。参数是列表。所以我应该传递带列表的不同函数。
(setq l1 (list 1 2 3))
(setq l2 (list 2 3 4))
(setq l3 (list 3 4 5))
(defmacro runner (fun &rest arg)
; some code
)
(defun summer (l)
(reduce #'+ l))
(print (runner summer l1 l2 l3))
就像这样,但是有任意数量的参数。
(defun runner (l)
(mapcar #'(lambda (x) (summer x)) l))
(print (runner (list l1 l2 l3)))
您需要在宏中使用反引号,因此它会在运行时扩展为对函数的调用,而不是编译时。
(defmacro runner (fun &rest arg)
`(mapcar (lambda (a) (funcall #',fun a)) (list ,@arg)))
(setq l1 (list 1 2 3))
(setq l2 (list 2 3 4))
(setq l3 (list 3 4 5))
(defun summer (l)
(reduce #'+ l))
(print (runner summer l1 l2 l3))
(print (runner (lambda (x) (+ x 1)) 1 3 4))
由于 runner
期望第一个参数是函数名,它在调用函数之前添加了 #'
前缀。所以当你调用它时,你不应该在 lambda
之前使用它。
我将 apply
更改为 funcall
,因为您调用 summer
的方式表明您希望每个列表作为单个参数传递,而不是传播。由于您的 lambda
表达式期望其参数是单个数字,而不是列表,因此我将数字作为单独的参数传递,而不是包含在列表中。
我需要传递函数并使用指定的参数调用它。如何正确地将 lambda 函数传递给宏并避免此错误:
APPLY: #'(LAMBDA (X) (+ X 1)) is not a function name; try using a symbol instead
代码:
(defmacro runner (fun &rest arg)
(apply fun arg))
通话:
(runner #'(lambda (x) (+ x 1)) '(1))
我的代码有什么问题?用 +
函数尝试了类似的东西,一切正常。
更新: 程序应该为每个参数和 return 结果调用指定的函数。参数是列表。所以我应该传递带列表的不同函数。
(setq l1 (list 1 2 3))
(setq l2 (list 2 3 4))
(setq l3 (list 3 4 5))
(defmacro runner (fun &rest arg)
; some code
)
(defun summer (l)
(reduce #'+ l))
(print (runner summer l1 l2 l3))
就像这样,但是有任意数量的参数。
(defun runner (l)
(mapcar #'(lambda (x) (summer x)) l))
(print (runner (list l1 l2 l3)))
您需要在宏中使用反引号,因此它会在运行时扩展为对函数的调用,而不是编译时。
(defmacro runner (fun &rest arg)
`(mapcar (lambda (a) (funcall #',fun a)) (list ,@arg)))
(setq l1 (list 1 2 3))
(setq l2 (list 2 3 4))
(setq l3 (list 3 4 5))
(defun summer (l)
(reduce #'+ l))
(print (runner summer l1 l2 l3))
(print (runner (lambda (x) (+ x 1)) 1 3 4))
由于 runner
期望第一个参数是函数名,它在调用函数之前添加了 #'
前缀。所以当你调用它时,你不应该在 lambda
之前使用它。
我将 apply
更改为 funcall
,因为您调用 summer
的方式表明您希望每个列表作为单个参数传递,而不是传播。由于您的 lambda
表达式期望其参数是单个数字,而不是列表,因此我将数字作为单独的参数传递,而不是包含在列表中。