如何在Scheme中取消定义变量?

Eon*_*nil 16 variables scheme undefined

如何在Scheme中取消定义变量?这可能吗?

Lui*_*las 7

你在这里感动神经.Scheme没有关于顶级环境如何工作的非常明确的标准概念.为什么?因为Scheme标准代表了两组人之间的妥协,他们对Scheme应该如何工作的想法截然不同:

  • 解释人群,如上所述,您可以看到顶级环境:运行时哈希表,其中随着程序解释的进行逐步添加绑定.
  • 然后是汇编人群,他们将顶级环境视为必须在编译时完全可计算的东西(即,编译器必须能够最终确定将在顶级环境中绑定的所有名称).

您的"我如何取消定义变量"问题仅在第一个模型中有意义.

请注意,解释模型(程序的顶级绑定取决于所采用的代码路径)使得有效编译Scheme代码变得更加困难,原因很多.例如,如果过程的名称是顶级绑定,并且可能不仅在运行时更改,甚至消失为虚无,那么Scheme编译器如何内联过程调用?

我坚定地在这里的编译阵营,所以我建议你避免编写依赖于在运行时添加或删除顶级绑定的代码,或者甚至需要使用顶级变量(虽然这些通常是不可避免的).一些Scheme系统(例如,Racket)能够产生相当好的编译代码,但是如果你做出这些假设,你就会在这方面绊倒它们.


小智 5

在Scheme中,变量用lambda或各种let之一定义.如果你想让其中一个被"未定义",那么你需要做的只是留下它们所在的范围.当然,这并不是真正取消它们,只是变量不再绑定到它之前的定义.

如果您使用(define)进行顶级定义,那么从技术上讲,您将定义一个函数.由于Scheme功能正常,功能永远不会消失.我认为从技术上讲,它存储在某种环境函数中,所以如果你非常熟悉你的实现(并且它不以某种方式得到保护),你可能会用你自己的globabl环境定义来覆盖它.除此之外,我会说你最好的选择是重新定义函数以返回空列表 - 这真的是空的.


cev*_*ing 5

Scheme ( R7RS ) 没有标准兼容的方法来删除顶级绑定。

如果您评估一个不存在的变量,则会出现错误:

(eval 'a)
; => ERROR: undefined variable: a
Run Code Online (Sandbox Code Playgroud)

如果您定义它,该变量将被添加到顶级环境中。

(define a 1)
(eval 'a)
; => 1
Run Code Online (Sandbox Code Playgroud)

从现在开始,无论您做什么,如果您访问该变量,都不会出错。

如果将其设置为 false,则会得到 false:

(set! a #f)
(eval 'a)
; => #f
Run Code Online (Sandbox Code Playgroud)

即使您将其设置为未指定的内容,也不太可能出现错误:

(set! a (if #f #t))
(eval 'a)
; =>
Run Code Online (Sandbox Code Playgroud)

但是Schemes 可能有一种非标准的方法来删除顶级绑定。MIT Scheme 提供了这个功能unbind-variable