Почему Racket по-разному обрабатывает мутацию в REPL и мутацию, используя как окно определения, так и REPL?

Обычно я избегаю использования мутаций, поскольку они редко нужны.

Однако они мне нужны, и я пытаюсь кое-что понять. Есть специфическое поведение, которое меня заинтриговало, и я хотел бы попросить вашей помощи, чтобы лучше понять его.

Если я наберу REPL, все изменения будут работать:

> (define x 1)
> (set! x (+ x 1))
> x
2

Если я помещу назначение и мутацию в окно определения, это также сработает:

(define y 1)
y
(set! y (+ y 1))
y

После запуска файла я вижу в REPL следующий правильный результат:

1
2
>

Однако, если я помещу определение переменной x в окна определения и попытаюсь установить! его на новое значение в REPL я получаю сообщение об ошибке:

; Definition Window

(define y 1)

;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;

; REPL

> (set! y (+ y 1))
. . y: cannot modify a constant

Почему это происходит? Не следует ли использовать интерактивное программирование специально для подобных ситуаций?

Заранее спасибо.


person Pedro Delfino    schedule 31.03.2021    source источник
comment
Может быть, см. здесь (я не знаю ).   -  person Carcigenicate    schedule 01.04.2021


Ответы (1)


По словам Маттиаса Феллейзена, одного из главных ответственных за разработку Racket:

DrRacket REPL позволяет использовать set!s для тех переменных, которые можно назначать в модуле, и ни для каких других. Это по дизайну. Грубо говоря, подумайте об окне «Определения» как о модуле, а о REPL — как о способе выполнения вычислений, как если бы мы были клиентом модуля, который также может использовать все свои внутренние определенные функции, подумайте о суперклиенте. Но это супер-клиентское представление не позволяет вам изменять переменные, которые изначально не были изменяемыми... точно так же, как клиент не может этого делать.

Эта информация была представлена ​​в списке рассылки Racket за 7 лет. назад, как указано в комментарии к моему собственному вопросу в сообщении выше.

person Pedro Delfino    schedule 31.03.2021