首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在mit-scheme中实现“定义宏”是可能的吗

在mit-scheme中实现“定义宏”是可能的吗
EN

Stack Overflow用户
提问于 2013-03-21 23:45:54
回答 2查看 2.1K关注 0票数 2

在阅读了this page之后。我发现很难记住如何用define-syntax代替define-macro,所以我想在麻省理工学院的方案中实现define-macro (或者至少找到一些等效的东西)。

下面是我的(有问题的)实现:

代码语言:javascript
复制
(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抱怨道:

代码语言:javascript
复制
;The object (lambda (test . branch) (list (quote if) test (cons (quote begin) branch))) is not applicable.

我是个新手,不知道哪里出了问题,有人能帮我吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-21 23:55:04

首先,你应该学会使用准引号,这样你的宏就更容易阅读。如下所示:

代码语言:javascript
复制
(define-macro (my-when test . branch)
  `(if ,test
     (begin ,@branch)))

不过,更重要的是,使用syntax-rules编写它非常容易,而且您真的应该比define-macro更喜欢它。

代码语言:javascript
复制
(define-syntax-rule (my-when test branch ...)
  (if test
    (begin branch ...)))

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

代码语言:javascript
复制
(define-syntax define-syntax-rule
  (syntax-rules ()
    ((define-syntax-rule (name . pattern) template)
     (define-syntax name
       (syntax-rules ()
         ((name . pattern) template))))))

注意,使用define-syntax-rule,简单的宏变得非常非常容易编写。下面是另一个例子:

代码语言:javascript
复制
(define-syntax-rule (let ((name value) ...)
                      expr ...)
  ((lambda (name ...)
     expr ...)
   value ...))
票数 6
EN

Stack Overflow用户

发布于 2014-06-21 08:22:34

如果你真的需要定义宏语义,你可以在mit-scheme中得到一个合理的近似值,如下所示:

代码语言:javascript
复制
(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定义为:

代码语言:javascript
复制
(define-macro (my-when test . branch)
  `(if ,test (begin ,@branch)))
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15552057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档