【发布时间】:2014-07-16 22:13:59
【问题描述】:
受comment thread 的启发,关于函数而不是宏的相关问题。
有什么方法可以扩展一个 Scheme 语法定义,使它可以在新定义中使用之前定义的语法?此外,它必须是可扩展的,也就是说,它必须可以多次链接该技术。
例如,假设我们要扩展lambda,这样每次调用lambda 定义的函数时,它都会在执行函数体之前打印“foo”。我们可以通过以下方式做到这一点:
(define-syntax old-lambda lambda)
(define-syntax lambda
(syntax-rules ()
((_ args body ...)
(old-lambda args (display "foo") body ...))))
我们还可以通过执行以下操作以另一种方式扩展它(例如,通过打印“bar”):
(define-syntax old-lambda-2 lambda)
(define-syntax lambda
(syntax-rules ()
((_ args body ...)
(old-lambda-2 args (display "bar") body ...))))
最终结果是,使用我们的新 lambda 定义的函数将在每次调用它们时打印“foo”,然后打印“bar”。
但是,除了使用大量old-lambda-<x> 污染命名空间之外,每次我们这样做时都需要在源代码级别创建一个新的old-lambda-<x>;这不能自动化,因为你也不能在语法定义中使用gensym。因此,没有很好的方法可以使其可扩展;唯一可行的解决方案是将每个名称命名为old-lambda-print-foo 或类似于消除歧义的名称,这显然不是万无一失的解决方案。 (举个失败的例子,假设代码的两个不同部分扩展 lambda 以打印“foo”;自然,他们都将其命名为 old-lambda-print-foo,瞧!lambda 现在是无限的循环。)因此,如果我们能够以理想的方式做到这一点,那就太好了:
- 不需要我们用大量的
old-lambda-<x>污染命名空间 - 或者,如果做不到这一点,保证我们不会发生冲突。
【问题讨论】:
标签: inheritance macros scheme r5rs