首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >真正理解过程化和函数化之间的区别

真正理解过程化和函数化之间的区别
EN

Stack Overflow用户
提问于 2011-03-08 06:31:34
回答 9查看 56.7K关注 0票数 116

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

下面是Wikipedia上关于函数式编程的条目的前两段

在计算机科学中,函数式编程是一种编程范例,它将计算视为数学函数的求值,并避免状态和可变数据。它强调函数的应用,而命令式编程风格则强调状态的变化。函数式编程起源于lambda演算,lambda演算是20世纪30年代开发的一个研究函数定义、函数应用和递归的正式系统。许多函数式编程语言都可以看作是对lambda演算的详细阐述。

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

在第2段中它说

相反,在函数代码中,函数的输出值仅取决于函数的输入参数,因此使用参数x的相同值调用函数f两次将产生相同的结果f(x)

这不就是过程式编程的完全相同的情况吗?

在过程性vs函数式中,人们应该寻找什么?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2011-03-12 13:13:44

函数式编程

函数式编程指的是将函数视为值的能力。

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

在函数式编程中,我们可以使用像composelift这样的运算符将两个函数值组合在一起来生成一个新的函数值。或者,我们可以使用像mapfold这样的运算符将函数值和数据值组合在一起来生成新的数据值。

请注意,许多语言都具有函数式编程功能--甚至通常不认为是函数式语言的语言也是如此。即使是老式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));
}

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

  1. compose(odd, length)oddlength函数组合在一起,以生成一个新函数,该函数确定字符串的长度是否为words中的每个元素调用该新函数,最终返回一个新的布尔值列表,每个布尔值列表指示相应的单词是否具有奇数个布尔值将“characters.
  2. apply(and, ...)”运算符应用于结果列表,并将所有布尔值加在一起以产生最终结果。

从这些示例中可以看出,过程性编程非常关注在变量中移动值,并显式地描述产生最终结果所需的操作。相比之下,函数式风格强调将初始输入转换为最终输出所需的函数组合。

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

进一步阅读

这个问题经常出现..。例如,请参阅:

John Backus的图灵奖演讲详细阐述了函数式编程的动机:

Can Programming Be Liberated from the von Neumann Style?

我真的不应该在目前的上下文中提到这篇论文,因为它变得非常技术性,非常迅速。我只是无法抗拒,因为我认为它是真正的基础。

附录- 2013

评论员指出,流行的当代语言提供了除过程性和函数性之外的其他编程风格。这些语言通常提供以下一种或多种编程风格:

批量数据查询(例如,列表理解、语言集成的query)

  • dataflow (例如,隐式迭代)、批量operations)

  • object-oriented (例如,封装的数据和methods)

  • language-oriented (例如,应用特定的语法、宏)

)(例如,应用程序特定的语法、宏)

  • query (例如,列表理解、语言集成的宏(例如,隐式迭代)、批量数据(例如,封装的数据和宏(例如,应用特定的语法、宏)

请参阅下面的注释,了解此响应中的伪代码示例如何从其他样式提供的一些工具中受益。特别是,程序示例将受益于几乎任何更高级别的构造的应用。

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

票数 281
EN

Stack Overflow用户

发布于 2011-03-08 06:42:58

函数式编程和命令式编程之间的真正区别在于思维方式--命令式编程人员考虑的是变量和内存块,而函数式编程人员考虑的是"How can I transform my input data to my Output data“-您的”程序“是将数据从输入转换到输出的管道和转换集。这是有趣的部分,而不是“你不能使用变量”的部分。

由于这种思维模式,FP程序通常描述将要发生的事情,而不是它将如何发生的具体机制-这是强大的,因为如果我们能够清楚地说明“选择”、“何处”和“聚合”的含义,我们就可以自由地交换它们的实现,就像我们使用AsParallel()所做的那样,我们的单线程应用程序突然扩展到n核。

票数 46
EN

Stack Overflow用户

发布于 2011-03-08 06:37:43

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

不,因为过程性代码可能会有副作用。例如,它可以在调用之间存储状态。

也就是说,可以用被认为是过程化的语言来编写满足这个约束的代码。也可以用某些被认为是函数式的语言来编写打破这种约束的代码。

票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5226055

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档