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

问题描述

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

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).

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

10-14 20:50