Scheme REPL是否可以重置用户环境?

9

Scheme新手问题-

有没有一种方法可以重置当前的REPL环境(即默认用户环境),而不需要退出和重新启动REPL?基本上,我希望有一种方法可以清除我的当前环境,以使我的先前定义都不再生效。这是使用GNU/MIT Scheme。

如果这是不可能的,那么当在REPL中尝试代码时,最佳实践是什么?我听说过人们谈论创建和删除软件包,但大多数示例似乎都是针对有点不同的通用Lisp。

我确实发现了如何在Clojure REPL中执行此操作的信息,但存在警告,并且似乎是特定于Clojure: Can I clean the repl?

谢谢!

编辑:从功能上讲,我能够通过退出和重新启动REPL进程来实现同样的效果。我找到了一种方法,但是使用vim-screen可以保持与我的编辑器(vim)的连接。如果没有办法在REPL内部执行此操作,则这是一种可接受的解决方案。但是,我会继续保持问题开放一段时间,看看是否有一种方法可以在语言内部执行此操作,因为我认为这将是有益的。


你可以尝试停止REPL并重新启动它,这样行吗? - compman
是的,但我更喜欢下面给出的解决方案,因为我可以将该表达式保留在我的文本缓冲区中,并将其发送到REPL而不离开我的编辑器,而重新启动REPL需要我实际上切换到其窗口,运行退出命令,然后调用一个新的REPL,这需要更长的时间。 - Eliot
1个回答

12

我认为这取决于具体的实现方式,但在 MIT Scheme 中,您可以使用以下命令清除 REPL 环境:

1 ]=> (ge (make-top-level-environment))

函数(ge [environment])的作用是"将当前REP循环环境更改为[environment]",而函数make-top-level-environment则会"返回一个新分配的顶层环境"。

MIT Scheme有许多环境管理函数可以查看,链接在这里

我在Mac OS X(10.6.7)上测试了这个功能,在GNU网站提供的预编译二进制文件中安装了MIT Scheme 9.0.1,并进行了以下REPL会话:

1 ]=> (define foo 1)

;Value: foo

1 ]=> foo

;Value: 1

1 ]=> (ge (make-top-level-environment))

;Value 13: #[environment 13]

1 ]=> foo

;Unbound variable: foo
;To continue, call RESTART with an option number:
; (RESTART 3) => Specify a value to use instead of foo.
; (RESTART 2) => Define foo to a given value.
; (RESTART 1) => Return to read-eval-print level 1.

2 error> 

我认为不同的Scheme实现有不同的约定,但我认为没有任何一个像Common Lisp的包管理机制那样特别。如果你不是非常固执于MIT Scheme,可以尝试一下Racket和Dr Racket,它是一个很好的IDE,比命令行上的普通REPL更强大,而且我想它有某种模块系统。Racket是Scheme的一种方言,因此根据你的需求,可能并不适合(Racket中默认的语言模块与MIT Scheme不同)。

最近(过去几个月)我一直在探索运行Lisp in Small Pieces代码的Scheme实现,其中有许多奇怪的宏,最后Gambit成为了最佳选择。但如果你不需要这样的需求,不妨看看Racket。


我之前已经阅读过这份文档,但仍不清楚如何完成我想要做的事情。上面的步骤似乎可行,但只能使用一次,并且可能会产生一些危险的副作用。它所做的是将当前环境切换到系统全局环境。之后,我所做的任何定义都会在全局环境中生效。此外,REPL现在处于更危险的模式,因为我可以在全局范围内重新定义标准过程。我想做的是创建一个全新的环境,它是系统全局环境的子级,然后切换到该环境。 - Eliot
我正在使用MIT Scheme,因为我在跟随MIT OpenCourseware 6.001班级 http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/,它是课程的文本和现有学生使用的Lisp方言。Racket看起来很有趣... 我能把它当作等效于MIT-Scheme并忽略它的其他功能,直到我以后需要它吗? - Eliot
我不确定你所说的“危险副作用”是什么意思,可以举个例子吗?我可以在全新的REPL中重新定义carcdr等,而不需要影响环境。 - okonomichiyaki
1
你也可以尝试(ge (make-top-level-environment)),但我不知道它和之前的有什么区别。 - okonomichiyaki
我认为切换到全局环境可以规避这个问题:“尽管系统全局环境中的所有绑定都可见于REP循环,但在REP循环中输入或加载的定义将出现在用户初始环境中。这在某种程度上是一项安全措施:如果您输入一个与关键系统过程同名的定义,则您的定义仅对您在用户初始环境中定义的过程可见;MIT / GNU Scheme系统过程仍将在系统全局环境中定义,将继续查看原始定义。” - Eliot
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接