0

I'm learning how the macro system in Scheme works and I'm trying to make my code look more JavaScript-y. So I thought I would start with the function macro. This is how I want a function definition to look:

(function id (x) x)

It should expand to the following:

(define (id x) x)

So I write a macro as follows:

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

However when I use it I get the following error (in 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)    <--

Where am I going wrong? In addition how do I read such error messages to be able to debug the program myself?

4

2 回答 2

4

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

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

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

以上保证卫生。

于 2013-04-14T13:04:41.143 回答
2

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

宏应定义为:

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

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

于 2013-04-14T11:27:47.760 回答