你怎么能在Scheme中重写“开始”?

时间:2009-11-05 21:33:35

标签: scheme

正如Wikipedia文章所解释的那样,Scheme中的begin是一个图书馆表单,可以使用更基本的表单(如lambda)重写。

但是你如何重写begin,尤其是考虑以下内容?

x
===> error: undefined identifier: x
(begin (define x 28) x)
===> 28
x
===> 28

2 个答案:

答案 0 :(得分:18)

你做不到。问题是begin有两个角色:一个是序列一组副作用表达式,另一个是它用于“拼接”宏结果。您可以将begin与上面的定义一起使用,这是第二个功能的结果,您无法自己编写。

如果您真的想要关注整个故事,那么您可以begin定义为简单的宏,这使得它只执行排序方面(它确实可以如此实现,虽然通常不是)。 但是,您需要将begin的显式识别添加到拼接定义(顶层或内部)。这意味着宏实现很好,但它实际上不是一个库,因为核心扩展器应该知道它。 (并且因为语言是词法​​范围的,所以核心扩展器没有好的方法来识别核心语言中没有定义的begin。)

总结所有这些,你可以说R5RS在将begin归类为“库语法”时是错误的,因为它不能在库中定义......但即使这样也不完全准确R5RS将“库语法”定义为“派生表达式”。因此,真正错误的一点是begin的两个面之一在扩展器(用于定义上下文)中的其他地方实现。

另请注意,R6RS澄清了整个交易:begin的两个面是明确的,它现在是核心语言的一部分,而不是“库形式”,甚至不是派生形式。< / p>

答案 1 :(得分:2)

您仍然可以尝试编写满足其第一个角色的开头版本:排序。

(define-syntax sequencing
  (syntax-rules ()
    [(_ expression) expression]
    [(_ expression expressions ...)
     ((lambda (ignored) (sequencing expressions ...)) expression)]))

这是我从中获取该片段的帖子。如果你是interested,它会提供更好的上下文,而你可能是。