真正理解程序和功能之间的区别

我真的很难理解程序和函数编程范例之间的区别。

以下是维基百科关于函数式编程的前两段:

在计算机科学中,函数式编程是一种编程范式,将计算视为数学函数的评估并避免状态和可变数据。 它强调功能的应用,与强调状态变化的命令式编程风格形成鲜明对比。 函数式编程的根源在于lambda演算,这是20世纪30年代开发的一个正式系统,用于调查函数定义,函数应用和递归。 许多函数式编程语言可以被看作是lambda演算的详细描述。

在实践中,数学函数与命令式编程中使用的“函数”概念之间的区别在于,命令式函数会产生副作用,从而改变程序状态的值。 因此,它们缺乏参考透明度,即相同的语言表达式可能会在不同的时间导致不同的值,具体取决于正在执行的程序的状态。 相反,在函数代码中,函数的输出值仅依赖于输入到函数的参数,所以用参数x的相同值调用函数f两次将产生两次相同的结果f(x) 。 消除副作用可以使得更容易理解和预测程序的行为,这是功能程序开发的关键动机之一。

在第2段中说

相反,在函数代码中,函数的输出值仅依赖于输入到函数的参数,所以用参数x的相同值调用函数f两次将产生两次相同的结果f(x)

与程序编程不一样吗?

在程序功能和功能性方面,应该注意什么?


功能编程

函数式编程是指将函数作为值来对待的能力。

我们来考虑一下“常规”值的类比。 我们可以取两个整数值并使用+运算符来组合它们以获得新的整数。 或者我们可以用一个浮点数乘一个整数来得到一个浮点数。

在函数式编程中,我们可以将两个函数值结合起来,使用组合或提升等运算符产生新的函数值。 或者我们可以结合一个函数值和一个数据值来使用诸如map或fold之类的运算符产生一个新的数据值。

请注意,许多语言都具有功能性编程功能 - 即使是通常不被认为是功能性语言的语言。 即使祖父FORTRAN也支持函数值,尽管它没有提供很多功能组合操作符。 对于被称为“功能性”的语言,它需要大规模地支持功能性编程功能。

程序编程

程序编程是指将一个通用的指令序列封装到一个过程中的能力,以便这些指令可以在很多地方被调用而不需要复制和粘贴。 由于程序是编程中的一个非常早期的发展,其能力几乎总是与机器或汇编语言编程所要求的编程风格相联系:强调存储位置和指令在这些位置之间移动数据的概念的风格。

对比

这两种风格并不完全相反 - 它们只是彼此不同。 有些语言完全支持这两种风格(例如LISP)。 以下情况可能会让您对两种风格有所区别。 让我们编写一些代码,用于确定列表中的所有单词是否具有奇数个字符的情况。 一,程序风格:

function allOdd(words) {
  var result = true;
  for (var i = 0; i < length(words); ++i) {
    var len = length(words[i]);
    if (!odd(len)) {
      result = false;
      break;
    }
  }
  return result;
}

我会认为这个例子是可以理解的。 现在,功能风格:

function allOdd(words) {
  return apply(and, map(compose(odd, length), words));
}

从内到外,这个定义做了以下几件事:

  • compose(odd, length)组合oddlength函数来产生一个新函数,该函数确定一个字符串的长度是否为奇数。
  • map(..., words)words每个元素调用新函数,最终返回一个新的布尔值列表,每个布尔值表示相应的单词是否具有奇数个字符。
  • apply(and, ...)将“和”运算符应用于结果列表,并将所有布尔值集合在一起以产生最终结果。
  • 您可以从这些示例中看到,过程式编程非常关心在变量中移动值并明确描述产生最终结果所需的操作。 相反,功能风格强调将初始输入转换为最终输出所需的功能组合。

    该示例还显示了程序代码与功能代码的典型相对大小。 此外,它表明程序代码的性能特征可能比功能代码更容易看到。 考虑:函数计算列表中所有单词的长度,还是每个函数在找到第一个偶数长度单词后立即停止? 另一方面,功能代码允许高质量的实现来执行一些非常严格的优化,因为它主要表达意图而不是显式算法。

    进一步阅读

    这个问题出现了很多......例如:

  • 过程式编程和函数式编程有什么区别?
  • 有人能给我一些函数式编程与命令式/程序式编程的例子吗?
  • OOP与功能编程vs程序
  • John Backus的图灵奖讲座详细阐述了函数式编程的动机:

    编程能否从冯诺依曼风格中解放出来?

    我不应该在目前的情况下提及这篇论文,因为它非常快速,技术性很强。 我无法抗拒,因为我认为这是真正的基础。


    附录 - 2013年

    评论家指出,流行的当代语言除了程序和功能外,还提供其他风格的程序设计。 这些语言通常提供以下一种或多种编程风格:

  • 查询(例如列表解析,语言集成查询)
  • 数据流(例如隐式迭代,批量操作)
  • 面向对象(如封装的数据和方法)
  • 面向语言(例如特定于应用程序的语法,宏)
  • 请参阅下面的注释以获取有关此响应中的伪代码示例如何从这些其他类型的一些可用设施中受益的示例。 特别是,程序性例子将从几乎任何更高级别的构造的应用中受益。

    所展示的例子有意避免混合这些其他编程风格,以强调所讨论的两种风格之间的区别。


    功能和命令式编程的真正区别在于心态 - 命令式编程人员正在考虑变量和内存块,而功能程序员正在考虑“如何输入数据转换为我的输出数据” - 您的“程序”是管道以及对数据进行变换以将其从输入变为输出。 这是IMO的有趣部分,而不是“你不应该使用变量”位。

    作为这种思维方式的结果,FP计划通常会描述将会发生什么,而不是它将如何发生的具体机制 - 这是非常有用的,因为如果我们能够清楚地说明“选择”和“哪里”以及“聚合”的含义,我们可以自由地替换它们的实现,就像我们使用AsParallel()一样,突然我们的单线程应用扩展到n个核心。


         Isn't that the same exact case for procedural programming?
    

    不,因为程序代码可能有副作用。 例如,它可以在呼叫之间存储状态。

    也就是说,可以用程序语言编写满足这个约束条件的代码。 并且还可以编写代码,以便在某些被认为功能正常的语言中打破这种约束。

    链接地址: http://www.djcxy.com/p/80579.html

    上一篇: Truly understanding the difference between procedural and functional

    下一篇: Tail Recursion in F# : Stack Overflow