在阅读了this page之后。我发现很难记住如何用define-syntax代替define-macro,所以我想在麻省理工学院的方案中实现define-macro (或者至少找到一些等效的东西)。
下面是我的(有问题的)实现:
(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)))而REPL抱怨道:
;The object (lambda (test . branch) (list (quote if) test (cons (quote begin) branch))) is not applicable.我是个新手,不知道哪里出了问题,有人能帮我吗?
发布于 2013-03-21 23:55:04
首先,你应该学会使用准引号,这样你的宏就更容易阅读。如下所示:
(define-macro (my-when test . branch)
`(if ,test
(begin ,@branch)))不过,更重要的是,使用syntax-rules编写它非常容易,而且您真的应该比define-macro更喜欢它。
(define-syntax-rule (my-when test branch ...)
(if test
(begin branch ...)))哦,你以前没见过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))))))注意,使用define-syntax-rule,简单的宏变得非常非常容易编写。下面是另一个例子:
(define-syntax-rule (let ((name value) ...)
expr ...)
((lambda (name ...)
expr ...)
value ...))发布于 2014-06-21 08:22:34
如果你真的需要定义宏语义,你可以在mit-scheme中得到一个合理的近似值,如下所示:
(define-syntax define-macro
(syntax-rules ()
((define-macro (name . args) body ...)
(define-syntax name
(rsc-macro-transformer
(let ((transformer (lambda args body ...)))
(lambda (exp env)
(apply transformer (cdr exp)))))))))然后,您可以将my-when定义为:
(define-macro (my-when test . branch)
`(if ,test (begin ,@branch)))https://stackoverflow.com/questions/15552057
复制相似问题