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

Variables 如何在Scheme中取消定义变量?,variables,scheme,undefined,Variables,Scheme,Undefined,如何在Scheme中取消定义变量?这可能吗?您不能在标准方案中解除变量绑定。你可以设定!我猜变量是“未定义的”,或者您可以编写一个元解释器来具体化环境,允许您引入自己的未定义变量概念。您不能在标准方案中解除变量绑定。你可以设定!我想,变量是“未定义的”,或者您可以编写一个元解释器来具体化环境,允许您介绍自己的未定义变量概念。在Scheme中,变量是用lambda或各种let之一定义的。如果您希望其中一个是“未定义的”,那么您所需要做的就是离开它们所在的范围。当然,这并不是真的取消定义它们,只是变

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

您不能在标准方案中解除变量绑定。你可以设定!我猜变量是“未定义的”,或者您可以编写一个元解释器来具体化环境,允许您引入自己的未定义变量概念。

您不能在标准方案中解除变量绑定。你可以设定!我想,变量是“未定义的”,或者您可以编写一个元解释器来具体化环境,允许您介绍自己的未定义变量概念。

在Scheme中,变量是用lambda或各种let之一定义的。如果您希望其中一个是“未定义的”,那么您所需要做的就是离开它们所在的范围。当然,这并不是真的取消定义它们,只是变量不再绑定到它以前的定义


如果您正在使用(define)进行顶级定义,那么从技术上讲,您正在定义一个函数。由于Scheme是功能性的,所以功能永远不会真正消失。我认为从技术上讲,它存储在某个环境函数中,因此如果您非常熟悉您的实现(而且它没有受到保护),您可能会使用您自己的globabl环境定义来覆盖它。除此之外,我认为最好的办法是重新定义函数以返回空列表-它实际上是空的。

在Scheme中,变量是用lambda或各种let之一定义的。如果您希望其中一个是“未定义的”,那么您所需要做的就是离开它们所在的范围。当然,这并不是真的取消定义它们,只是变量不再绑定到它以前的定义

(set! no-longer-needed #f)
如果您正在使用(define)进行顶级定义,那么从技术上讲,您正在定义一个函数。由于Scheme是功能性的,所以功能永远不会真正消失。我认为从技术上讲,它存储在某个环境函数中,因此如果您非常熟悉您的实现(而且它没有受到保护),您可能会使用您自己的globabl环境定义来覆盖它。除此之外,我认为您最好的选择是重新定义函数以返回空列表-它实际上是空的

(set! no-longer-needed #f)
这能达到你想要的效果吗?您还可以在顶层使用define

guile> (define nigel "lead guitar")
guile> nigel
"lead guitar"
guile> (define nigel #f)
guile> nigel
#f
guile> 
然后可以重新定义变量。当然,这取决于变量的范围:请参阅

这能达到你想要的效果吗?您还可以在顶层使用define

guile> (define nigel "lead guitar")
guile> nigel
"lead guitar"
guile> (define nigel #f)
guile> nigel
#f
guile> 

然后可以重新定义变量。当然,这一切都取决于变量的范围:请参阅。

我认为,如果您的目的是执行“免费”或取消分配的等效操作,那么不,您的运气太差了。不能取消分配变量。您可以将其重新定义为较小的值,如#f,但一旦完成(定义foo’bar),变量foo将以某种形式存在,直到您结束程序


另一方面,如果你使用let,或者letrec,当然,这个名字只存在到相关的关闭paren…

我认为,如果你的目的是做“免费”或取消分配,那么不,你很不走运。不能取消分配变量。您可以将其重新定义为较小的值,如#f,但一旦完成(定义foo’bar),变量foo将以某种形式存在,直到您结束程序


另一方面,如果您使用let或letrec,当然,该名称仅在相关的关闭参数出现之前存在…

您在这里触碰了神经。Scheme对于顶级环境如何工作没有非常清晰的标准概念。为什么?因为方案标准代表了两组人之间的折衷,他们对方案应该如何工作有着截然不同的想法:

  • 解释人群,他们看到了上面描述的顶级环境:一个运行时哈希表,其中绑定随着程序解释的进行而逐渐添加
  • 然后是编译人群,他们认为顶级环境在编译时必须是完全可计算的(即,编译器必须能够最终确定将绑定到顶级环境中的所有名称)
您的“如何定义变量”问题仅在第一个模型中有意义

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


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

你触动了神经。Scheme对于顶级环境如何工作没有非常清晰的标准概念。为什么?因为方案标准代表了两组人之间的折衷,他们对方案应该如何工作有着截然不同的想法:

  • 解释人群,他们看到了上面描述的顶级环境:一个运行时哈希表,其中绑定随着程序解释的进行而逐渐添加
  • 然后是编译人群,他们认为顶级环境在编译时必须是完全可计算的(即,编译器必须能够最终确定将绑定到顶级环境中的所有名称)
你的“我该怎么做?”
(define my-list (cons 2 my-list))
(eval 'a)
; => ERROR: undefined variable: a
(define a 1)
(eval 'a)
; => 1
(set! a #f)
(eval 'a)
; => #f
(set! a (if #f #t))
(eval 'a)
; =>