正如 Wikipedia 文章所述,Scheme 中的 begin
是一种库形式,可以使用更基本的形式(如 lambda
)进行重写。
但是你如何重写 begin
,特别是考虑到以下几点?
x
===> error: undefined identifier: x
(begin (define x 28) x)
===> 28
x
===> 28
最佳答案
你不能。关键是begin
有两个作用:一个是对一堆有副作用的表达式进行排序,另一个是用来“拼接”宏结果。您可以使用具有上述定义的 begin
的事实是第二个功能的结果,您不能自己编写它。
如果您真的想了解整个故事,那么您可以将 begin
定义为简单的宏,使其仅执行排序方面的工作(并且确实可以这样实现,尽管通常不是)。但是,您需要将 begin
的显式识别添加到拼接定义(顶级或内部)。这意味着宏实现很好,但它不能真正成为库,因为核心扩展器应该知道它。 (并且因为语言是词法范围的,核心扩展器没有好的方法来识别核心语言中未定义的 begin
s。)
总结所有这些,您可以说 R5RS 仅将 begin
分类为“库语法”是错误的,因为它不能在库中定义……但即使这样也不完全准确,因为 R5RS 将“库语法”定义为只是“派生表达式”。因此,真正错误的一点是,begin
的两个面之一在扩展器中的其他地方实现(用于定义上下文)。
另请注意,R6RS 澄清了整个问题: begin
的两个面是明确的,现在它是核心语言的一部分,不是“库形式”,甚至不是派生形式。
关于scheme - 如何在 Scheme 中重写 "begin"?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1683796/