схема ракетного переопределения констант - PullRequest
0 голосов
/ 14 января 2011

В настоящее время я использую схему ракетки с DrRacket в качестве редактора для некоторого исследовательского программирования.Когда я пытаюсь переопределить функцию, я получаю следующее сообщение:

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

Теперь я привык к тому, что это свойство языка и было разочаровано им, но отчасти принимал его.Прочитав Как вы можете переопределить постоянный идентификатор в DrScheme? Я вижу, что мне не обязательно принимать это ограничение.

У меня следующие вопросы:

  1. Эта функция доступна только на языке R5RS?Есть ли способ отключить эту функцию для произвольного языка?
  2. В качестве альтернативы, если я переключу язык R5RS, это повлияет на меня при использовании модулей, которые я использую в данный момент: racket / gui / baseа веб-сервер / инста?

Ответы [ 3 ]

4 голосов
/ 14 января 2011

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

0 голосов
/ 14 ноября 2013

Вот как определить умножение

(определить умножение *); переменная с именем «multiply» со значением *

0 голосов
/ 14 января 2011

1 - я не профессионал в Схеме, но я просто попытался переопределить функцию умножения (*). Не работает с «Запретить переопределение начальных привязок». Но если не проверено - работает:

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
>

Однако я не смог получить вашу ошибку (define-values: не могу переопределить константу: ...) Если я переопределяю существующую функцию, я получаю (define-values: не могу изменить постоянную переменную: ...)

2 - Я думаю, что если в модулях есть директива #lang, которая явно определяет язык, это не должно быть проблемой (я думаю).

...