0

我目前正在使用带有 DrRacket 的球拍方案作为一些探索性编程的编辑器。当我尝试重新定义一个函数时,我收到以下消息:

define-values: cannot re-define a constant: png->byte-list

现在我曾经接受这是语言的一个属性,并且对此感到沮丧,但还是接受了它。阅读了如何在 DrScheme 中重新定义常量标识符?我可以看到我不一定要接受这个限制。

我的问题如下:

  1. 此功能是否仅在 R5RS 语言中可用?有没有办法为任意语言关闭此功能?
  2. 或者,如果我切换 R5RS 语言,这是否会对我使用我目前正在使用的模块产生影响:racket/gui/base 和 web-server/insta?
4

3 回答 3

4

#lang racket如果您在定义窗口中进行此类重新定义,则可以进行此类重新定义。要记住的是,这不是一种突变(这在 R5RS 实现中很常见),例如:

#lang racket
(define orig-+ +)
(define + whatever)

不会orig-+绑定到真正的加法函数。当这个模块被编译时,Racket (静态地)知道这+是你定义的东西,所以对它的任何引用都是对你自己定义的引用——所以上面的代码将绑定orig-++. 如果你真的想做这样的事情,那么你可以要求原件+使用不同的名称:

#lang racket
(require (rename-in racket [+ orig-+]))
(define + whatever)

最重要的是,编译模块时会发生内联——这是一个不同的问题。Racket 通常希望内联对代码中从未发生变化的绑定的引用,因此如果您尝试最后一段代码,您将无法+在 REPL 上进一步重新定义。您可以通过以下两种方式之一来处理它——第一种是显式地改变绑定:

#lang racket
(require (rename-in racket [+ orig-+]))
(define + #f)
(set! + whatever)

这使得编译器避免任何内联。另一种选择是 DrRacket 标志,它打开一个避免所有内联的编译器标志。请注意,这样做的速度损失可能很大。

于 2011-01-14T14:10:44.483 回答
0

1 - 我不是 Scheme 的专家,但我只是试图重新定义乘法函数 (* )。它不适用于“不允许重新定义初始绑定”。但如果未选中 - 它可以工作:

Welcome to DrRacket, version 5.0.2 [3m].
Language: R5RS [custom]; memory limit: 128 MB.
> (* 2 2)
4
> (define (* a b) a)
> (* 2 2)
2
>

但是,我无法得到您的错误(定义值:无法重新定义常量:...)如果我重新定义现有函数,我会得到(定义值:无法更改常量变量:...)

2 - 我认为如果模块具有明确指定语言的#lang 指令,它应该不是问题(我猜)。

于 2011-01-14T11:26:16.880 回答
0

以下是如何定义乘法

(定义乘 *) ; 名为“multiply”的变量,值为 *

于 2013-11-14T15:43:37.820 回答