Такие переопределения возможны с #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, который включает флаг компилятора, который позволяет избежать всякого встраивания. Обратите внимание, что штраф за скорость может быть значительным.