我最近一直在研究Scheme,我遇到了一个函数,它的定义如下:
(define remove!
(let ((null? null?)
(cdr cdr)
(eq? eq?))
(lambda ... function that uses null?, cdr, eq? ...)绑定null的目的是什么?设置为null?或者cdr到cdr,当这些是在没有let块的函数定义中可用的函数中构建的?
发布于 2010-07-10 01:50:45
在普通的R5RS方案中,没有模块系统--只有顶层。此外,心态是一切都可以修改,所以你可以以任何你想要的方式“定制”语言。但如果没有模块系统,这就不能很好地工作。例如,我写道
(define (sub1 x) (- x 1))在您加载的库中--现在您可以重新定义-
(define - +) ; either this
(set! - +) ; or this现在你无意中破坏了我的库,这个库依赖于sub1将它的输入减少一,结果当你把它们拖下来的时候,你的窗口就会升起,或者其他什么。
解决这个问题的唯一方法是,在有人修改之前,“抓取”减法函数的相关定义:
(define sub1 (let ((- -)) (lambda (x) (- x 1))))现在事情会“更好”,因为您不能通过更改-来修改我的sub1函数的含义。(除了...如果您在加载我的库之前修改它...)
无论如何,由于这一点(如果您知道在装入库时-是原始的),一些编译器将检测到这一点,并看到-调用将始终是实际的减法函数,因此它们将内联对它的调用(内联对-的调用最终会导致汇编代码减去两个数字,因此这是一个很大的速度提升)。但就像我在上面的评论中所说的,这与上面的实际原因更加巧合。
最后,R6RS (以及之前的几个方案实现)已经解决了这个问题,并添加了一个库系统,因此这个技巧没有任何用处:只要库中的其他代码没有以某种方式重新定义-,sub1代码就是安全的,并且编译器可以基于此安全地优化代码。不需要巧妙的把戏。
发布于 2010-07-09 22:50:29
这是一个速度优化。局部变量访问通常比全局变量更快。
https://stackoverflow.com/questions/3213638
复制相似问题