Macros 我的宏在Common Lisp中部分应用时出现问题

Macros 我的宏在Common Lisp中部分应用时出现问题,macros,common-lisp,currying,Macros,Common Lisp,Currying,我正在尝试制作一个宏来实现CommonLisp中的部分应用。以下是我如何用伪代码实现的想法: If my argument list is null, return the function body Otherwise, cons together "lambda" with the first argument with a recursive call to "partial-lambda" again (lambda (x y z) (+ x y

我正在尝试制作一个宏来实现CommonLisp中的部分应用。以下是我如何用伪代码实现的想法:

If my argument list is null, return the function body
Otherwise, cons together "lambda" with the first argument with a recursive call to "partial-lambda" again

(lambda (x y z) (+ x y z) => (lambda (x) (lambda (y) (lambda (z) (+ x y z))))
这是我的密码:

(defmacro部分lambda(参数和静止体)
(如果(空参数)正文
(lambda((汽车参数))(部分lambda(cdr参数)车身)))
(部分λ(x y z)(+x y z))
不幸的是,SBCL给了我这个错误:

; in: DEFMACRO PARTIAL-LAMBDA
;     (LAMBDA (CAR PARAMS) (PARTIAL-LAMBDA (CDR PARAMS) BODY))
; ==>
;   #'(LAMBDA (CAR PARAMS) (PARTIAL-LAMBDA (CDR PARAMS) BODY))
; 
; caught STYLE-WARNING:
;   The variable CAR is defined but never used.

; file: /Users/caspianahlberg/Desktop/Programming/Lisp/partial_application.lisp
; in: DEFMACRO PARTIAL-LAMBDA
;     (PARTIAL-LAMBDA (CDR PARAMS) BODY)
; 
; caught STYLE-WARNING:
;   undefined function: COMMON-LISP-USER::PARTIAL-LAMBDA
; 
; compilation unit finished
;   Undefined function:
;     PARTIAL-LAMBDA
;   caught 2 STYLE-WARNING conditions
STYLE-WARNING:
   PARTIAL-LAMBDA is being redefined as a macro when it was previously assumed to be a function.
为什么它会抱怨汽车从未被使用过?我觉得这很令人困惑。熟悉CL宏的人知道我做错了什么吗?

试试这个:

(defmacro partial-lambda (params &rest body)
    (if (null params) `(progn ,@body)
        `(lambda (,(car params)) (partial-lambda ,(cdr params) ,@body))))

CL-USER 43 > (partial-lambda (x y z) (+ x y z))
#<anonymous interpreted function 40300008DC>

CL-USER 44 > (funcall * 10)
#<anonymous interpreted function 403000094C>

CL-USER 45 > (funcall * 15)
#<anonymous interpreted function 40300009BC>

CL-USER 46 > (funcall * 3)
28
(defmacro部分lambda(参数和静止体)
(如果(空参数)`(progn,@body)
`(lambda(,(汽车参数))(部分lambda,(cdr参数),@body)))
CL-USER 43>(部分λ(x y z)(+x y z))
#是的变体,允许在其内部取消引号,当您希望在引号内的部分中取消引用某些内容时,使用(该表达式将替换为值)。并且,@(取消引号拼接)取消引号,替换它并删除该值周围的括号。这些操作通常在Lisp宏中使用


编辑:
(车身)
替换为
`(progn,@body)
,用于处理车身中包含更多表达式的输入:
(部分lambda(x y z)(打印5)(+x y z))
语法错误

(lambda((汽车参数))(部分lambda(cdr参数)车身))

Common Lisp需要一个参数列表作为lambda表单的第二个元素。参数是一个符号。不计算参数列表

您的代码有一个列表
(汽车参数)
作为第一个参数。但Common Lisp需要一个符号

您的示例也与您显示的错误不匹配。

也许你做到了:

(defmacro partial-lambda (params &rest body)
  (if (null params)
      body
      (lambda (car params) (partial-lambda (cdr params) body))))
但是,您可以使用参数
car
params
定义一个参数列表。这毫无意义。这就是为什么Lisp编译器抱怨变量
car
未使用的原因

宏对代码进行操作

记住,宏需要返回代码。使用列表运算符或反引号表达式创建代码

反引号表达式如下所示(参见Martin půda的答案):


反向报价允许评估列表模板的选定部分。逗号计算并插入结果。逗号符号用于计算和拼接中的结果列表。

仅供参考,亚历山大港有
咖喱
`(lambda (,(car params)) (partial-lambda ,(cdr params) ,@body))