是否有可能在mit-scheme中实现"define-macro"

Jav*_*ran 0 scheme mit-scheme

看完这个页面.我发现很难记住如何使用define-syntax代替define-macro,所以我想define-macro在mit-scheme中实现(或者至少找到一些等价物).

这是我的(有问题的)实现:

(define-syntax define-macro
  (rsc-macro-transformer
    (let ((xfmr (lambda (macro-name macro-body)
      (list 'define-syntax macro-name
        (list 'rsc-macro-transformer
          (let ((m-xfmr macro-body))
            (lambda (e r)
              (apply m-xfmr (cdr e)))))))))
      (lambda (e r)
        (apply xfmr (cdr e))))))

(define-macro my-when
  (lambda (test . branch)
    (list 'if test (cons 'begin branch))))

(my-when #t
  (begin
    (display "True")
    (newline)))
Run Code Online (Sandbox Code Playgroud)

REPL抱怨说:

;The object (lambda (test . branch) (list (quote if) test (cons (quote begin) branch))) is not applicable.
Run Code Online (Sandbox Code Playgroud)

我刚接触计划并且不知道出了什么问题,有人可以帮助我吗?

Chr*_*ung 6

首先,你应该学习使用准规则,这样你的宏就更容易阅读.像这样:

(define-macro (my-when test . branch)
  `(if ,test
     (begin ,@branch)))
Run Code Online (Sandbox Code Playgroud)

但更严重的是,这很容易使用syntax-rules,你真的应该非常喜欢它define-macro.

(define-syntax-rule (my-when test branch ...)
  (if test
    (begin branch ...)))
Run Code Online (Sandbox Code Playgroud)

哦,你以前没见过define-syntax-rule?它是一个简单的宏,可以用来编写一个子句define-syntax宏,它定义如下:

(define-syntax define-syntax-rule
  (syntax-rules ()
    ((define-syntax-rule (name . pattern) template)
     (define-syntax name
       (syntax-rules ()
         ((name . pattern) template))))))
Run Code Online (Sandbox Code Playgroud)

请注意,使用define-syntax-rule简单的宏如何变得非常容易编写.这是另一个例子:

(define-syntax-rule (let ((name value) ...)
                      expr ...)
  ((lambda (name ...)
     expr ...)
   value ...))
Run Code Online (Sandbox Code Playgroud)