首页 文章

球拍方案重新定义常数

提问于
浏览
0

我目前正在使用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 回答

  • 4

    如果在定义窗口中执行此操作,则可以使用 #lang racket 进行此类重新定义 . 需要记住的是,这不是一种突变(这与R5RS实现相同),例如:

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

    不会有 orig-+ 绑定到真正的添加功能 . 编译此模块时,Racket(静态地)知道 + 是您定义的内容,因此对它的任何引用都是对您自己定义的引用 - 因此上面的代码将 orig-+ 绑定到"uninitialized"的"uninitialized" . 如果你真的想做类似的事情,那么你可以在不同的名称下要求原始的 +

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

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

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

    这使编译器避免任何内联 . 另一种选择是DrRacket标志,它打开一个避免所有内联的编译器标志 . 请注意,对此的速度惩罚可能很大 .

  • 0

    1 - 我不是Scheme中的专家,但我只是试图重新定义乘法函数(*) . 它不适用于“禁止重新定义初始绑定” . 但如果不加以控制 - 它有效:

    欢迎来到DrRacket,版本5.0.2 [3m] .
    语言:R5RS [custom];内存限制:128 MB .
    (* 2 2)
    4
    (定义(* a b)a)
    (* 2 2)
    2

    但是,我无法得到你的错误(define-values:不能重新定义一个常量:...)如果我重新定义现有函数我得到(define-values:不能改变常量变量:...)

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

  • 0

    以下是如何定义乘法

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

相关问题