【发布时间】:2012-06-03 05:22:41
【问题描述】:
假设我想在 s 表达式中的第一项以外的其他内容上触发 Scheme 宏。例如,假设我想用中缀样式的:= 替换define,这样:
(a := 5) -> (define a 5)
((square x) := (* x x)) -> (define (square x) (* x x))
实际的转换似乎很简单。诀窍是让 Scheme 找到 := 表达式并对其进行宏扩展。我考虑过使用标准宏(可能是:(with-infix-define expr1 expr2 ...))围绕使用中缀语法的大部分代码,并让标准宏遍历其主体中的表达式并执行任何必要的转换。我知道如果我采用这种方法,我将不得不小心避免转换实际上应该是数据的列表,例如引用列表和准引用列表的某些部分。我设想的一个例子:
(with-infix-define
((make-adder n) := (lambda (m) (+ n m)))
((foo) :=
(add-3 := (make-adder 3))
(add-6 := (make-adder 6))
(let ((a 5) (b 6))
(+ (add-3 a) (add-6 b))))
(display (foo))
(display '(This := should not be transformed))
所以,我的问题有两个:
- 如果我走
with-infix-define路线,除了quote 和quasiquote 之外,我还需要注意任何绊脚石吗? - 我感觉有点像在重新发明轮子。这种类型的代码遍历似乎正是标准宏扩展系统必须做的 - 唯一的区别是它们在决定是否进行任何代码转换时只查看列表中的第一项.有什么方法可以搭载现有系统?
【问题讨论】:
-
Scheme 是否有 code-walker 包?似乎您需要做的就是将代码包装在 with-macro 中,遍历该代码并将 := 与之前的 s-exp 交换,然后定义一个使 := 等效于 define 的符号宏。但不确定引用的 s-exps。