什么是编程语言中的不变量,为什么它很重要?

时间:2016-01-12 23:04:33

标签: programming-languages invariants

任何人都可以解释编程语言中的不变量是什么以及它们为何重要?

2 个答案:

答案 0 :(得分:4)

不变量是您希望始终保持的数据属性。不变量非常重要,因为它们允许您将业务逻辑与验证分开 - 您的函数可以安全地假设它们没有收到无效数据。

例如,在国际象棋游戏中,你有一个不变量,即每次只有一件可能占据棋盘上的给定方格。不变量可以在编译时强制执行,通常通过使用静态类型系统来通过构造使对象正确,例如通过将板表示为可选块的矩阵。它们也可以在运行时强制执行,例如,在尝试进行无效移动时引发异常。

函数式编程语言中的方法通常是使对象不可变,并防止构造无效状态。在OOP语言中,对象通常是可变的,期望方法防止无效状态转换

无论哪种方式,强制执行不变量都可确保您的程序始终处于可预测状态,这样可以更轻松地推理代码并安全地进行更改,而不会引入回归。

答案 1 :(得分:4)

什么是不变量

任何字段中的不变量 - 是允许您区分"对象"的值(通常是数字)。如果那些不变量不一样。

例如,如果你有一个数学术语说

(x+3)²+1

并且您希望将一个不变量替换为x的替代随机数,我的rng选择了x=0 - 所以不变量将是

(0+3)²+1 = 9+1 = 10

然后如果我错误地改变了术语

x²+6x+3 + 1 = x² + 6x +4

再次使用x = 0进行测试我看到0²+0+4 = 410不同,因此我知道必须有错误。 但另一方面,如果我将这个词改为

x²+3x+9 +1 = x²+3x+10

x=0的不变量将再次为10 - 所以我们看到了

为什么它们有用?

  • 不同的不变量=>不同的对象
  • 相同的不变量=>也许是同一个对象

示例:equational reasoning

为什么这会在(功能)编程中变得有趣 - 你将在这个上下文中听到的一个表达式是equational reasoning,这意味着如果你可以将算法/函数/术语转换为另一个没有失去平等。对于像haskell这样的语言,通过限制不变性,没有副作用等,这通常是正确的。而在oo中,这通常是不正确的。均衡推理可以缩小错误发生的区域,因此调试/查找错误相对容易。

示例:property based testing

不变量常见的另一个字段是基于属性的测试:这里reverse :: [a] -> [a]的标准示例,即(链接)列表上的反向函数,具有reverse . reverse == id的属性,即反转两次是就像无所事事一样。 如果你把它放在Quickcheck测试中 - 测试生成器生成任意列表并检查这个属性 - 如果其中一个(可能)数千个测试失败你知道,在哪里改进你的代码。

示例:Compiler optimizations

某些属性也可用于优化代码,例如,对于所有函数fmap f . fmap g == fmap (f . g)并且左侧遍历数据结构两次,其中右侧只进行一次遍历,编译器可以替换他们让你的代码快两倍。