【问题标题】:Why its important for a functional language to support immutable types? [closed]为什么函数式语言支持不可变类型很重要? [关闭]
【发布时间】:2016-07-02 19:27:51
【问题描述】:

正如here 所讨论的那样,我们现在知道判断一种语言是否具有功能性的特征是什么。但是不可变性在什么情况下适合这种情况呢?

【问题讨论】:

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


    【解决方案1】:

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

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

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

    这里的笑话是,我们将命令式、以命令为导向的思维与数学、函数式思维混合在一起。在命令式风格中,x 是一个变量,这意味着我们假设它的值可能会随着时间而变化。但是当我们做数学时,我们做了一个不同的假设:我们假设“x”是一个特定的值,这意味着一旦我们知道“x”的值,我们就可以在“x”出现的任何地方替换这个值。该假设是能够解方程的全部基础。显然,如果“x”的值从我们下面改变,就像上面心理练习的第 2 行那样,那么所有的赌注都没有了。第 2 行不是有效的数学运算,因为语句 x = x + 1 在数学上不成立。 (至少就我在高中数学中学到的而言!)

    另一种看待它的方式是说命令式编程混合了值、函数和状态,这使得它很难推理。因为“x”的值可能会因您查看它的时间而有所不同,所以您不能仅仅通过查看代码就很容易知道它会对您的代码运行方式产生什么影响。您必须“玩编译器”并在精神上跟踪所有变量以及它们如何随时间变化,而这很快就会变得难以管理。状态是计算机编程中附带复杂性的第一大来源。

    函数式编程通过将状态与函数分离来简化事情。在像f(x) = (x * x) 这样的数学函数中,“x”的值不会随时间变化。这是对“x”和“f(x)”之间关系的纯粹描述,无论你先看“x”还是“f(x)”,这种关系总是正确的。不涉及任何国家。您正在描述值之间的关系,与时间无关,并且没有任何状态。而且由于您不必担心状态会从您身下发生变化,因此您可以更轻松、更安全地推断输入和输出之间的关系。

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

    所有这一切中真正酷的是,即使“x”是一个比简单数字更复杂的东西,也是如此。你可以编写纯函数,其参数是数组、记录、客户对象等,同样的原则仍然适用。通过保持你的函数纯净和你的值不可变,你正在编写描述函数参数和函数输出之间关系的代码,而不会附带时间和状态的复杂性。这是巨大的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-23
      • 2016-03-31
      • 2011-02-25
      • 2017-01-14
      • 2010-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多