可变和不可变类型背后的理论是什么?

时间:2011-07-02 01:52:50

标签: python immutability mutable language-theory

我钦佩Python的一个原因是它区分了可变类型和不可变类型。在进入Python之前花了一段时间在c编程,我很惊讶Python如何轻松地消除指针解除引用的所有复杂性,这让我很生气。在Python中,一切都按照我期望的方式工作,我很快意识到可变/不可变的区别在其中起着重要作用。

当然还有一些皱纹(可变函数参数默认是一个值得注意的例子)但总的来说,我觉得可变/不可变的区别大大澄清了哪些变量及其值是以及他们应该如何表现。

但是它来自哪里?我必须假设GvR不是第一个设想这种区别的人,并且Python不是第一个使用它的语言。我很想听听使用这个概念的早期语言,以及对它的任何早期理论讨论。

4 个答案:

答案 0 :(得分:7)

如果您喜欢不变性的想法,那么您应该查看纯函数式语言。在Haskell 中,所有(纯)变量都是不可变的(但仍然被称为“变量”,但是你去了)。这是一个好主意 - 你和编译器都知道将某些内容传递给函数不能以任何方式改变它。

答案 1 :(得分:5)

在C中没有明确的不可变概念,因为该语言基于复制语义。在Python中,值总是通过引用传递,而不变性在保持语言可管理性方面起着重要作用。

在Python中你没有指针,因为一切都是指针!想象一下,对于一个Python程序来说,甚至数字对象可能会随着时间的推移而改变价值......对于你来说,你会被迫玩弄像

这样的技巧
class Shape:
    def __init__(self, points):
        self.points = points[:] # make a copy of the list

不仅适用于列表和dicts,还适用于数值和字符串。

因此,基本上在Python中,某些类型具有不可变实例,因为它们通常用作“值”而您不关心身份。在极少数情况下,您需要一个带有数值的可变对象,您需要在类实例中明确地将其包装起来。

在其他语言中,基本上基于参考语义如LISP不变性是程序员留下的选择而不是约束,即使许多函数和习惯用语支持它(LISP标准库函数的很大一部分是非破坏性的,它确实是有点遗憾的是,破坏性的并不总是可以通过名称清楚地区分出来。)

因此,例如字符串是可变的LISP,但可能没有多少LISP程序实际修改字符串,因为这意味着放弃共享的良好可能性,并且需要在许多地方显式复制字符串(在大多数情况下,字符串只是值,不是你关心身份的对象)。字符串在LISP中是不可变的吗?不是。节目是否会改变它们?几乎没有。

不向程序员选择是Python语言的精神。当你被迫做出的选择与你的想法一致时,感觉很棒...减少决定和事情就像你想要的那样。

然而,在我看来,这种方法存在两种不同的危险:

  1. 当这些预先做出的选择与您想要或不需要做的事情不符时,就会出现问题。 Python是一种很棒的语言,但是不同的独裁者可能会成为纯粹的地狱。

  2. 理解和制作选择会迫使你思考和扩展你的思想。不做出选择只是在你的脑海中留下一个笼子,过了一段时间你可能甚至没有意识到你所使用的只是一种可能性,而不是唯一的可能性。过了一段时间,你可能会开始认为“事情必须以这种方式完成”:你甚至不觉得自己被迫,因为你的思想已被“残缺”了。

答案 2 :(得分:4)

目标C加载了可变/不可变的区别(例如,有NSStringNSMutableString的点;它比Python早了大约8年。 Objectivet C继承了其大部分OO设计的Smalltalk在较小程度上使用了这个概念(特别是字符串不是不可变的;现在的趋势是不可变的字符串,如Python,Ruby等)。

答案 3 :(得分:-2)

我建议您阅读维基百科的以下条目: