捕获宏方案 [英] Capturing Macros in Scheme

查看:66
本文介绍了捕获宏方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是定义在球拍使用的拍摄微距的最简单的方法?

What's the simplest way to define a capturing macro using define-syntax or define-syntax-rule in Racket?

作为具体的例子,这里的琐碎在CL式宏系统.

As a concrete example, here's the trivial aif in a CL-style macro system.

(defmacro aif (test if-true &optional if-false)
    `(let ((it ,test))
        (if it ,if-true ,if-false)))

的想法是,将被绑定到的子句的结果.天真的音译(减去可选的替代项)是

The idea is that it will be bound to the result of test in the if-true and if-false clauses. The naive transliteration (minus optional alternative) is

(define-syntax-rule (aif test if-true if-false)
    (let ((it test))
       (if it if-true if-false)))

如果您尝试使用中的所有条款,其评价毫无怨言,但错误:

which evaluates without complaint, but errors if you try to use it in the clauses:

> (aif "Something" (displayln it) (displayln "Nope")))
reference to undefined identifier: it

anaphora egg aif实现为

(define-syntax aif
  (ir-macro-transformer
   (lambda (form inject compare?)
     (let ((it (inject 'it)))
       (let ((test (cadr form))
         (consequent (caddr form))
         (alternative (cdddr form)))
     (if (null? alternative)
         `(let ((,it ,test))
        (if ,it ,consequent))
         `(let ((,it ,test))
        (if ,it ,consequent ,(car alternative)))))))))

但球拍似乎不具有定义或记录.

but Racket doesn't seem to have ir-macro-transformer defined or documented.

推荐答案

球拍宏被设计为默认避免捕获.当您使用define-syntax-rule时,它将遵循词汇范围.

Racket macros are designed to avoid capture by default. When you use define-syntax-rule it will respect lexical scope.

当您要故意破坏卫生"时,传统上在Scheme中,您必须使用syntax-case,并且(请谨慎地)使用datum->syntax.

When you want to "break hygiene" intentionally, traditionally in Scheme you have to use syntax-case and (carefully) use datum->syntax.

但在球拍做照应"宏最简单,最安全的方法是使用语法参数和简单

But in Racket the easiest and safest way to do "anaphoric" macros is with a syntax parameter and the simple define-syntax-rule.

例如:

(require racket/stxparam)

(define-syntax-parameter it
  (lambda (stx)
    (raise-syntax-error (syntax-e stx) "can only be used inside aif")))

(define-syntax-rule (aif condition true-expr false-expr)
  (let ([tmp condition])
    (if tmp
        (syntax-parameterize ([it (make-rename-transformer #'tmp)])
          true-expr)
        false-expr)))

我写了一篇关于语法参数这里,你也应该阅读礼Barzilay的 肮脏的卫生学博客文章 清洁与语法参数纸(PDF)保持它

I wrote about syntax parameters here and also you should read Eli Barzilay's Dirty Looking Hygiene blog post and Keeping it Clean with Syntax Parameters paper (PDF).

这篇关于捕获宏方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆