Scheme 如果我对内置函数进行阴影处理,如何恢复它?

Scheme 如果我对内置函数进行阴影处理,如何恢复它?,scheme,racket,Scheme,Racket,举个例子: (define sqrt (lambda (x) (* 2 (sqrt x)))) (sqrt 2) 2.828427 ... 如何调用原始内置sqrt过程而不重新启动解释器(或取消阴影定义) 实际上,当我们这样做时,内部会发生什么?内置的是否被覆盖,或者两个过程是否在不同的名称空间中共存?您对sqrt的定义实际上会导致堆栈溢出,因为它会在自身中递归,而不是内置的sqrt:-P 无论如何,在Racket中,您对sqrt的定义只会影响您当前的模块。可以用不同的名称重新导入内置的sqr

举个例子:

(define sqrt (lambda (x) (* 2 (sqrt x))))
(sqrt 2)
2.828427 ...
如何调用原始内置
sqrt
过程而不重新启动解释器(或取消阴影定义)


实际上,当我们这样做时,内部会发生什么?内置的是否被覆盖,或者两个过程是否在不同的名称空间中共存?

您对
sqrt
的定义实际上会导致堆栈溢出,因为它会在自身中递归,而不是内置的
sqrt
:-P

无论如何,在Racket中,您对
sqrt
的定义只会影响您当前的模块。可以用不同的名称重新导入内置的
sqrt
,并从特定于模块的
sqrt
调用该名称:

(require (rename-in racket/base [sqrt racket-sqrt]))
(define sqrt (lambda (x) (* 2 (racket-sqrt x))))

请注意,您的代码不会影响未导入模块的
sqrt
定义的其他模块;他们将继续使用内置的
sqrt

,至少在Racket 6.5中我没有看到任何堆栈溢出。我可以调用我的
sqrt
,它会给我
2*racket\u sqrt
,也就是说,它不会自己递归。这就是我不明白的
(sqrt 10000)=>200
@DanielG您正在交互窗口中定义
sqrt
它。如果在定义窗口中执行此操作,将导致堆栈溢出。好的,我明白了。如果我在“定义”窗口中键入它,它确实会导致堆栈溢出。但是为什么不在交互窗口上呢?也许是个bug?但有一件事我可以肯定,交互窗口有自己的规则。例如,您可以多次定义同一id。写入
(define(foo)bar)
不会导致未绑定id错误,但会导致定义窗口中出现错误(这是为了让您稍后写入
(define bar 123)
)。我应该指出,这不是堆栈溢出,因为Racket不使用机器的堆栈。它只是耗尽了内存。