正如Wikipedia文章所解释的那样,Scheme中的begin
是一个图书馆表单,可以使用更基本的表单(如lambda
)重写。
但是你如何重写begin
,尤其是考虑以下内容?
x
===> error: undefined identifier: x
(begin (define x 28) x)
===> 28
x
===> 28
答案 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,它会提供更好的上下文,而你可能是。