可变类型和不可变类型背后的理论是什么?
我欣赏 Python 的原因之一是它对可变类型和不可变类型的区分。在使用 Python 之前,我已经用 C 语言编程了一段时间,我惊讶地发现 Python 如此轻松地消除了指针取消引用的所有复杂性,而这些复杂性让我在 C 语言中感到疯狂。在 Python 中,一切都按照我期望的方式工作,我很快意识到可变/不可变的区别在其中发挥着重要作用。
当然,仍然存在一些问题(可变函数参数默认值是一个值得注意的例子),但总的来说,我认为可变/不可变的区别极大地澄清了变量及其值是什么以及如何定义的问题。他们应该表现得好。
但它从哪里来呢?我必须假设 GvR 不是第一个想到这种区别的人,Python 也不是第一个使用它的语言。我有兴趣了解使用这个概念的早期语言,以及任何早期的理论讨论。
One of the things that I admire about Python is its distinction between mutable and immutable types. Having spent a while programming in c before coming to Python, I was astonished at how easily Python does away with all the complexities of pointer dereferencing that drive me mad in c. In Python everything just works the way I expect, and I quickly realized that the mutable/immutable distinction plays an important part in that.
There are still a few wrinkles, of course (mutable function argument defaults being a notable example) but overall, I feel that the mutable/immutable distinction greatly clarifies the question of what variables and their values are and how they ought to behave.
But where does it come from? I have to assume that GvR was not the first person to conceive of this distinction, and that Python was not the first language to use it. I'm interested in hearing about earlier languages that used this concept, as well as any early theoretical discussions of it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您喜欢不变性的想法,您应该查看纯函数式语言。在 Haskell 中,所有(纯)变量都是不可变的(但仍称为“变量”,但就是这样)。这是一个好主意 - 您和编译器都知道将某些内容传递给函数不能以任何方式更改它。
If you like the idea of immutability, you should check out a pure functional language. In Haskell all (pure) variables are immutable (yet still referred to as "variables", but there you go). It is a great idea - you and the compiler both know that passing something into a function cannot change it in any way.
在 C 中,没有明确的不可变概念,因为该语言基于复制语义。相反,在 Python 中,值总是通过引用传递,并且不变性在保持语言的可管理性方面发挥着重要作用。
在Python中你没有指针,因为一切确实都是指针!想象一下,对于一个 Python 程序来说,即使是数字对象也可能随着时间的推移而改变值,这意味着什么……你将被迫玩弄一些技巧,
不仅对列表和字典,而且对数值和字符串也如此。
所以基本上在 Python 中,某些类型具有不可变的实例,因为它们通常用作“值”,并且您不关心身份。在极少数情况下,例如您需要一个带有数值的可变对象,您需要将其显式包装在一个类实例中。
在其他基本上基于参考语义的语言中,如 LISP 不变性是留给程序员的选择,而不是一种约束,即使许多函数和惯用语都支持它(很大一部分 LISP 标准库函数是非破坏性的,它确实是一种遗憾的是,破坏性的东西并不总是能通过名称清楚地区分)。
例如,字符串是可变的 LISP,但可能没有多少 LISP 程序真正就地修改字符串,因为这意味着放弃共享的良好可能性,并且需要在许多地方显式复制字符串(在大多数情况下,字符串只是值,而不是对象)您关心身份)。 LISP 中的字符串是不可变的吗?不。程序会改变它们吗?几乎从来没有。
不给程序员留下选择权是 Python 语言的精神。当你被迫做出的选择符合你的想法时,感觉很棒……更少的决定,事情就像你想要的那样。
然而,在我看来,这种方法存在两种不同的危险:
当这些预先做出的选择与您想要或需要做的事情不一致时,就会出现问题。 Python 是一种很棒的语言,但如果换了一个独裁者,情况可能会变得纯粹地狱。
理解和做出选择会迫使你思考并拓展你的思维。不做选择只会给你的思想带来一个牢笼,过了一段时间你甚至可能没有意识到你所使用的只是一种可能性,而不是唯一的可能性。一段时间后,你可能开始只是认为“事情必须这样做”:你甚至不觉得自己是被迫的,因为你的思想已经被“残害”。
In C there is no explicit concept of immutable because the language is based on copy semantic. In Python instead values are always passed by reference and immutability plays an important role to keep the language manageable.
In Python you don't have pointers because everything is indeed a pointer! Imagine what it could mean for a Python program that even number objects could change value over time... you would be forced to play tricks like
not only for lists and dicts, but also for numeric values and strings.
So basically in Python some types have immutable instances because they normally are used as "values" and you don't care about identity. In the rare cases in which you need for example a mutable object with a numeric value you need to explicitly wrap it up in say a class instance.
In other languages substantially based on reference semantic like LISP immutability is a choice left to the programmer and not a constraint even if many functions and idioms are supporting it (a big percentage of LISP standard library functions are non-destructive and it's indeed sort of a shame that destructive ones aren't always clearly distinguishable by the name).
So for example strings are mutable LISP but probably not many LISP programs actually modify strings in place because that would mean giving up the nice possibility of sharing and would require explicitly copying strings in many places (in most cases strings are just values, not objects in which you care about identity). Are strings immutable in LISP? No. Are programs mutating them? Almost never.
Not leaving a choice to the programmer is in the spirit of the Python language. It feels great when the choices you are forced to are in line with your idea... less decisions and things are exactly like you wanted them to be.
There are however in my opinion two different dangers with this approach:
Problems arise when those pre-made choices are NOT in line on what you would like or need to do. Python is a wonderful language, but with a different dictator could become pure hell.
Understanding and making choiches forces you to think and expands your mind. Not making choices instead just puts a cage on your mind and after a while you may not even realize that what you are using is just ONE possibility, not the only possibility. After a while you may begin to just think that "things MUST be done this way": you don't even feel you are forced because your mind has already been "mutilated".
Objective C 具有可变/不可变的区别(例如,同时存在
NSString
和NSMutableString
);它比 Python 早大约 8 年。 Objective C 继承了 Smalltalk 的大部分 OO 设计,但在较小程度上使用了这个概念(值得注意的是,字符串不是不可变的;当今的趋势是使用不可变字符串,如 Python、Ruby 等)。Objective C is loaded with mutable/immutable distinctions (to the point where there are both
NSString
andNSMutableString
, for example); it predates Python by about 8 years. Smalltalk, from which Objective C inherited much of its OO design, uses the concept to a lesser extent (notably, strings are not immutable; the trend these days is towards immutable strings as in Python, Ruby, etc.).我建议阅读维基百科中的以下条目:
I'd recommend reading the following entries from Wikipedia: