【发布时间】:2011-10-13 20:46:34
【问题描述】:
为了自学更高级的球拍宏,我开始创建一个宏来增加可变结构中的字段:
(increment! instance name field)
=>
(set-name-field 实例 (get-name-field 实例))
我制作了一个有效的宏,并决定在多个模块之间共享它会很有用。不幸的是,由于结构变异器不在定义宏的模块范围内,因此会发生扩展错误。
以下是演示该问题的人为示例。我想知道:
我是否以惯用的球拍风格编写了宏代码?这是正确的方法吗?
如何控制宏的扩展,使其在存在未在其原始上下文中找到的标识符的情况下运行?
谢谢。
#lang racket/load
(module util racket
(define-syntax increment!
(lambda (stx)
(syntax-case stx ()
[(increment! s sn fn i)
(with-syntax
([set! (string->symbol
(format "set-~a-~a!" (syntax-e #'sn) (syntax-e #'fn)))]
[get (string->symbol
(format "~a-~a" (syntax-e #'sn) (syntax-e #'fn)))])
#'(set! s (+ i (get s))))]
;; default increment of 1
[(increment! s sn fn) #'(increment! s sn fn 1)])))
(provide increment!)
)
(module bank racket
(require 'util)
(struct money (dollars pounds euros) #:mutable #:transparent)
(let ([m (money 0 50 20)])
(increment! m money pounds 100)
(increment! m money dollars)
m)
)
(require 'bank)
结果
展开:模块中的未绑定标识符:set-money-pounds!
【问题讨论】:
标签: racket