2013-04-14 30 views
0

我正在学习Scheme中的宏系统如何工作,并试图让我的代码看起来更加JavaScript-y。所以我想我会从function宏开始。这就是我想要一个函数定义一下:在鸡计划中扩展宏时出错

(function id (x) x) 

,应该扩大到以下几点:

(define (id x) x) 

所以我写一个宏如下:

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

然而,当我使用它我得到以下错误(在鸡计划):

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) <-- 

我哪里错了?另外,如何阅读这些错误信息以便自己调试程序?

回答

4

在流程,使用语法规则():

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

您所看到的错误是明显鸡计划的编译器预计define-syntax第二种形式是一个宏扩展程序 - 它们通常需要参数重命名和比较标识符。您的宏中的lambda不会产生合适的功能 - syntax-rules

以上是保证卫生。

3

您根据Chicken文档定义宏的方式不正确。你的代码似乎更受Common Lisp宏的启发。退房的文档heredefine-syntax与变压功能:

宏应该定义为:

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

expr是整个宏观表达即(function id (x) x),注入和比较是传递给宏,同时特殊的实用功能执行宏观扩展。