racket - 为什么 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
为什么会这样?不应该特别在这种情况下使用交互式编程吗?
提前致谢。
解决方案
据 Matthias Felleisen介绍,迄今为止,他是 Racket 开发的主要负责人之一:
DrRacket REPL 允许在模块中分配的那些变量上设置!这是设计使然。粗略地说,将定义窗口视为一个模块,而 REPL 是一种执行计算的方式,就好像我们是模块的客户端一样,也可以使用其所有内部定义的功能,想想超级客户端。但是这个超级客户端视图不允许你改变一开始不可变的变量......就像客户端也不能那样做。
正如我在上面帖子中对我自己的问题的评论中指出的那样,该信息在 7 年前出现在Racket 的邮件列表中。
推荐阅读
- c# - 使用 C# WinForms,如何修改系统音频输出,即均衡音频?
- h2 - 连接到 H2 给出:org.h2.jdbc.JdbcSQLException:唯一索引或主键违规:
- python - What Google app engine Auth to use to only expose my "intranet" site only to my GSuite users?
- javascript - How can I centralize bootstrap tooltip call?
- nginx - Nginx 不在反向代理中缓存静态资产
- spring-boot - 如何在 Spring Data Jpa 中通过示例查询使用投影?
- c# - 将工作表复制到新工作簿时,EPPlus 中的 ArgumentOutOfRange 异常
- mysql - 解决 perl DBD::mysql UTF-8 错误
- java - 用于授权的 Java swagger 注释
- firebase - Firebase Functions 版本的“部署到多个环境”