Macros 在方案中展开宏时出错

Macros 在方案中展开宏时出错,macros,lisp,scheme,chicken-scheme,define-syntax,Macros,Lisp,Scheme,Chicken Scheme,Define Syntax,我正在学习Scheme中的宏系统是如何工作的,我正在努力使我的代码看起来更像JavaScript-y。所以我想从函数宏开始。这就是我希望函数定义的外观: (function id (x) x) 它应扩展到以下方面: (define (id x) x) 所以我写了一个宏,如下所示: (define-syntax function (lambda (name args . body) `(define (,name ,@args) ,@body))) 然而,当我使用它时

我正在学习Scheme中的宏系统是如何工作的,我正在努力使我的代码看起来更像JavaScript-y。所以我想从
函数
宏开始。这就是我希望函数定义的外观:

(function id (x) x)
它应扩展到以下方面:

(define (id x) x)
所以我写了一个宏,如下所示:

(define-syntax function
    (lambda (name args . body)
        `(define (,name ,@args) ,@body)))
然而,当我使用它时,我得到以下错误(在鸡方案中):

错误:在扩展“define”中的(define…)时,需要lambda列表:(define((函数id(x)x)。#)
通话记录:
(功能id(x)x)
(##sys#cons(##core#quote define)(##sys#cons(##sys#cons name args)body))
(##sys#cons(##sys#cons name args)body)

(##sys#cons name args)根据文档,您定义宏的方式不正确。您的代码似乎更受常见Lisp宏的启发。使用transformer功能查看
定义语法的文档:

宏应定义为:

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

expr是整个宏表达式,即
(函数id(x)x)
和inject和compare是在执行宏展开时传递给宏的特殊实用程序函数。

根据文档,您定义宏的方式不正确。您的代码似乎更受常见Lisp宏的启发。使用transformer功能查看
定义语法的文档:

宏应定义为:

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

expr是整个宏表达式,即
(函数id(x)x)
和inject和compare是在执行宏展开时传递给宏的特殊实用程序函数。

在Scheme中,使用语法-rules()

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


在Scheme中,使用语法-rules()保证上述内容的卫生性。

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


以上内容保证卫生。

这缺少
ir宏转换器
调用,因此无法开箱即用。在CHICKEN的旧版本中,它可能会起作用,但也会产生误导,因为默认语法转换器是
er宏转换器
,它不接受“inject”而接受“rename”。这缺少
ir宏转换器
调用,因此无法开箱即用。在CHICKEN的旧版本中,它可能会起作用,但也会产生误导,因为默认语法转换器将是一个
er宏转换器
,它不接受“inject”而接受“rename”。
(define-syntax function
  (syntax-rules ()
    ((function name (args ...) body ...)
     (define (name args ...) body ...))))