为什么功能语言支持不可变类型很重要?

时间:2016-03-16 18:14:13

标签: data-structures functional-programming programming-languages

正如所讨论的那样here我们现在知道告诉某种语言是否有效的特征是什么。但不变性在哪里适合这种情况?

1 个答案:

答案 0 :(得分:4)

这是一个快速的心理练习,用伪代码:

1) x = 5;
2) x = x + 1;
3) print x; // prints "6"
4) x = x
// THEREFORE 5 = 6

右?我们知道x是第1行的5,我们知道x是第3行的6,所以如果x = x,那么5必须等于6。

这里的笑话是,我们将命令式,命令式思维与数学,功能性思维相结合。在命令式样式中,x是一个变量,这意味着我们假设它的值可能随时间而变化。但是当我们做数学时,我们会做出不同的假设:我们假设" x"是一个特定的值,意味着一旦我们知道" x"的价值,我们就可以在任何地方替换该值" x"出现。该假设是能够求解方程的全部基础。显然,如果" x"的价值从我们下面改变,就像在上面的心理练习第2行中那样,然后所有的赌注都被取消了。第2行是无效的数学,因为没有值,语句x = x + 1在数学上是真的。 (至少就我在高中数学中所学到的一样!)

另一种看待它的方式是说命令式编程混合了值,函数和状态,这使得很难推理。因为" x"的价值可以根据您查看的时间而有所不同,只需查看代码,您就可以轻松了解它对代码运行方式的影响。你必须"玩编译器"并在心理上跟踪所有变量以及它们如何随着时间的推移而变化,并且很快变得无法管理。 State是计算机编程偶然复杂的头号来源。

函数式编程通过将状态与函数分离来简化事物。在像f(x) = (x * x)这样的数学函数中," x"的值不随时间而改变。它是" x"之间关系的纯粹描述。和" f(x)",无论你是否看到" x"这种关系总是正确的。首先或" f(x)"第一。没有涉及的州。您无论时间如何,没有任何状态,都在描述价值观之间的关系。而且,由于您不必担心状态从您的下方转移,您可以更轻松,更安全地推断您的输入和输出之间的关系。

不可变变量通过从代码中删除时间元素和变量元素来模拟这种无状态的数学推理。你仍然需要在某些时候改变你的状态,但你可以把它放到以后,只有在你的纯函数计算出正确的值才能存储之后才更新状态。通过将状态管理与纯函数分离,可以使编码更简单,更容易推理,并且通常更可靠。此外,测试纯函数要容易得多,因为不需要模拟或额外设置或其他状态模拟先决条件。

在这一切中真正酷的是,即使在" x"是一个更复杂的东西,只是一个简单的数字。您可以编写其参数为数组,记录,Customer对象等的纯函数,并且仍然适用相同的原则。通过保持函数纯净和值不可变,您可以编写描述函数参数和函数输出之间关系的代码,而不会出现时间和状态的偶然复杂性。这太棒了。