我目前正在使用DrRacket的球拍方案作为一些探索性编程的编辑器 . 当我尝试重新定义一个函数时,我得到以下消息:
define-values: cannot re-define a constant: png->byte-list
现在我曾经接受过,这是该语言的一个属性,并且对它感到沮丧,但有点接受它 . 阅读How can you re-define a constant identifier in DrScheme?我可以看到我不一定要接受这个限制 .
我的问题如下:
-
此功能仅适用于R5RS语言吗?有没有办法为任意语言关闭此功能?
-
或者,如果我切换R5RS语言,这会对我使用我目前使用的模块产生影响:racket / gui / base和web-server / insta?
3 回答
如果在定义窗口中执行此操作,则可以使用
#lang racket
进行此类重新定义 . 需要记住的是,这不是一种突变(这与R5RS实现相同),例如:不会有
orig-+
绑定到真正的添加功能 . 编译此模块时,Racket(静态地)知道+
是您定义的内容,因此对它的任何引用都是对您自己定义的引用 - 因此上面的代码将orig-+
绑定到"uninitialized"的"uninitialized" . 如果你真的想做类似的事情,那么你可以在不同的名称下要求原始的+
:最重要的是,在编译模块时会出现内联 - 这是一个不同的问题 . Racket通常希望内联对代码中从未变异的绑定的引用,因此如果您尝试最后一段代码,则无法在REPL上进一步重新定义
+
. 您可以通过以下两种方式之一来处理:第一种是明确地改变绑定:这使编译器避免任何内联 . 另一种选择是DrRacket标志,它打开一个避免所有内联的编译器标志 . 请注意,对此的速度惩罚可能很大 .
1 - 我不是Scheme中的专家,但我只是试图重新定义乘法函数(*) . 它不适用于“禁止重新定义初始绑定” . 但如果不加以控制 - 它有效:
但是,我无法得到你的错误(define-values:不能重新定义一个常量:...)如果我重新定义现有函数我得到(define-values:不能改变常量变量:...)
2 - 我认为如果模块有#lang指令明确指定语言它应该不是问题(我猜) .
以下是如何定义乘法
(定义乘法*);名为“multiply”的变量,值为*