在Chicken Scheme中扩展宏期间出错

时间:2013-04-14 10:15:44

标签: macros lisp scheme chicken-scheme define-syntax

我正在学习Scheme中的宏系统是如何工作的,我正在尝试使我的代码看起来更像JavaScript-y。所以我想我会从function宏开始。这就是我想要一个函数定义的样子:

(function id (x) x)

它应扩展到以下内容:

(define (id x) x)

所以我写一个宏如下:

(define-syntax function
    (lambda (name args . body)
        `(define (,name ,@args) ,@body)))

但是当我使用它时,我收到以下错误(在Chicken Scheme中):

Error: during expansion of (define ...) - in `define' - lambda-list expected: (define ((function id (x) x) . #<procedure (rename sym1348)>) #<procedure (compare s11400 s21401)>)

    Call history:

    <syntax>      (function id (x) x)
    <eval>    (##sys#cons (##core#quote define) (##sys#cons (##sys#cons name args) body))
    <eval>    (##sys#cons (##sys#cons name args) body)
    <eval>    (##sys#cons name args)    <--

我哪里错了?另外,如何阅读此类错误消息以便自己调试程序?

2 个答案:

答案 0 :(得分:4)

在Scheme中,使用syntax-rules():

(define-syntax function
  (syntax-rules ()
    ((function name (args ...) body ...)
     (define (name args ...) body ...))))

您看到的错误显然是Chicken Scheme的编译器期望第二种形式的define-syntax是宏扩展过程 - 它们通常需要用于重命名和比较标识符的参数。宏中的lambda不会生成合适的函数 - syntax-rules会这样做。

以上保证卫生。

答案 1 :(得分:2)

根据Chicken文档,您定义宏的方式不正确。您的代码似乎更受Common Lisp宏的启发。查看带有变压器功能的define-syntax的文档here

宏应定义为:

(define-syntax function
    (lambda (expr inject compare)
        `(define (,(cadr expr) ,@(caddr expr)) ,(cadddr expr))))

expr是整个宏表达式,即(function id (x) x),而inject和compare是在宏扩展时传递给宏的特殊效用函数。