gpt4 book ai didi

macros - 如何控制Scheme宏展开的顺序?

转载 作者:行者123 更新时间:2023-12-02 03:29:21 26 4
gpt4 key购买 nike

我正在使用 Racket 宏扩展 syntax-id-rules,其他一些方案实现以 identifier-syntax 的名称提供。这些允许您指定即使定义的标识符不在头部位置也会发生的宏扩展。例如:

(define hidden #f)
(define-syntax proxy
(syntax-id-rules (set!)
[(set! proxy v) (set! hidden v)]
[proxy hidden]))

将把标识符proxy设置为hidden的代理。这是一个无用的示例,但它说明了用法。

我发现自己处于这样一种情况,我想要一个全局普通宏,我们称之为foo,我想在某些使用像proxy这样的标识符宏的情况下覆盖它。也就是说,我希望能够做这样的事情:

(define-syntax foo
(syntax-rules ()
[(foo arg ...) 'default]))

(define hidden #f)
(define-syntax proxy
(syntax-id-rules (foo set!)
[(foo proxy arg ...) 'special]
[(set! proxy v) (set! hidden v)]
[proxy hidden]))

(foo proxy) ; should return 'special

但实际上最后一行返回 'default,因为 foo 宏在 proxy 宏之前展开。

有什么想法可以实现这些目标,但使用 proxy 标识符宏覆盖 foo 的默认宏定义吗?我并不专门致力于上述架构。

补充:这不适用于任何现实世界的使用,而是形式语义中理论点演示的一部分。

最佳答案

@soegaard 完美地解释了这一点。如果不修改宏扩展器,您无法直接执行您想要的操作。

为了扩展@soegaard的答案,这里有一种方法来模拟您所要求的内容。它本质上是进行“双调度”宏扩展。但正如 soegaard 指出的那样,根据您的目标,可能有一种更惯用的方法来实现您想要的目标。

#lang racket
(require (for-syntax syntax/parse))

(begin-for-syntax
(define (special-condition? id)
(and (identifier? id)
(regexp-match #rx"^p" ; starts with "p"
(symbol->string (syntax->datum id))))))

(define-syntax foo
(syntax-parser
[(_ special-case arg ...)
#:when (special-condition? #'special-case)
#'(special-case 'hidden-special-case-tag arg ...)]
; else
[(_ arg ...) #''default]))

(define hidden #f)
(define-syntax proxy
(syntax-id-rules (quote set!)
[(proxy (quote hidden-special-case-tag) arg ...) 'special]
[(set! proxy v) (set! hidden v)]
[(proxy arg ...) 'other]
[proxy hidden]))

(foo non-proxy) ; => 'default
(foo proxy) ; => 'special
(proxy) ; => 'other
proxy ; => #f
(set! proxy #t)
proxy ; => #t

关于macros - 如何控制Scheme宏展开的顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32011251/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com