首页 > 解决方案 > 为什么 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

为什么会这样?不应该特别在这种情况下使用交互式编程吗?

提前致谢。

标签: racketread-eval-print-loopmutation

解决方案


Matthias Felleisen介绍,迄今为止,他是 Racket 开发的主要负责人之一:

DrRacket REPL 允许在模块中分配的那些变量上设置!这是设计使然。粗略地说,将定义窗口视为一个模块,而 REPL 是一种执行计算的方式,就好像我们是模块的客户端一样,也可以使用其所有内部定义的功能,想想超级客户端。但是这个超级客户端视图不允许你改变一开始不可变的变量......就像客户端也不能那样做。

正如我在上面帖子中对我自己的问题的评论中指出的那样,该信息在 7 年前出现在Racket 的邮件列表中。


推荐阅读