函数式编程的核心概念是什么?

时间:2009-07-11 02:29:53

标签: functional-programming

在面向对象的编程中,我们可以说核心概念是:

  1. 封装
  2. 继承,
  3. 多态性
  4. 函数式编程会是什么?

6 个答案:

答案 0 :(得分:64)

关于函数式编程中的基本概念,没有社区共识。在 Why Functional Programming Matters (PDF),John Hughes认为它们是高阶函数和惰性评估。在Wearing the Hair Shirt: A Retrospective on Haskell中,西蒙佩顿琼斯说真正重要的不是懒惰而是纯洁。理查德伯德会同意。但是,有很多Scheme和ML程序员非常乐意编写带副作用的程序。

作为一名练习和教授函数式编程已有二十年的人,我可以给你一些被广泛认为是函数式编程核心的想法:

  • 具有适当词汇范围的嵌套,一流函数是核心。这意味着您可以在运行时创建匿名函数,其自由变量可以是封闭函数的参数或局部变量,您将获得可以返回的值,放入数据结构中,等等。 (这是高阶函数最重要的形式,但是一些高阶函数(如qsort!)可以用C编写,这不是一种函数式语言。)

  • 与其他功能组合功能以解决问题的方法。没有人比约翰休斯更好。

  • 许多功能程序员认为纯度(不受影响,包括变异,I / O和异常)是函数式编程的核心。许多功能程序员没有。

  • 多态性,无论是否由编译器强制执行,都是功能程序员的核心价值。令人困惑的是,C ++程序员将这一概念称为“通用编程”。当编译器强制执行多态时,它通常是Hindley-Milner的变体,但功能更强大的System F也是函数式语言的强大基础。使用Scheme,Erlang和Lua等语言,您可以在没有静态类型系统的情况下进行函数式编程。

  • 最后,绝大多数功能程序员都相信归纳定义数据类型的价值,有时称为“递归类型”。在具有静态类型系统的语言中,这些通常称为“代数数据类型”,但即使在material written for beginning Scheme programmers中也可以找到归纳定义的数据类型。归纳定义类型通常附带一种称为模式匹配的语言功能,它支持非常一般的案例分析形式。编译器通常会告诉您是否忘记了案例。我不想在没有这种语言功能的情况下进行编程(曾经采样的奢侈品变得必不可少)。

答案 1 :(得分:39)

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

简而言之,

  1. Lambda Calculus
  2. 高阶函数
  3. 不变性
  4. 无副作用

答案 2 :(得分:14)

不直接回答你的问题,但我想指出“面向对象”和函数式编程并不一定是不一致的。你引用的“核心概念”有更多的通用对应物,它们同样适用于函数式编程。

封装,更一般地说,是模块化。我所知道的所有纯功能语言都支持模块化编程。您可能会说这些语言比典型的“OO”类型更好地实现封装,因为副作用破坏了封装,而纯函数没有副作用

继承,更一般地说,是逻辑蕴涵,这是函数所代表的。规范subclass -> superclass关系是一种隐含函数。在函数式语言中,这用类型类含义表示(我认为暗示这两者中更为一般)。

“OO”学校的多态性是通过子类型(继承)实现的。有一种更普遍的多态性称为参数多态(a.k.a。泛型),您会发现纯函数式编程语言支持这种多态。另外,一些支持“更高种类”或更高阶的泛型(a.k.a。类型构造函数多态)。

我想说的是,你的“OO的核心概念”并不以任何方式特定于OO。举个例子,我认为事实上没有 OO的任何核心概念。

答案 3 :(得分:4)

让我重复我在班加罗尔功能编程小组的一次讨论中给出的答案:

功能程序仅包含功能。功能计算 他们的输入值。我们可以将其与命令进行对比 编程,程序执行的地方,可变的值 地点变化。换句话说,在C或Java中,一个名为X的变量 是指其值发生变化的位置。但在功能上 编程X是值的名称(不是位置)。任何地方 X在范围内,它具有相同的值(即,它是参考的 透明)。在FP中,函数也是值。他们可以作为传递 其他函数的参数。这被称为高阶函数 节目。高阶函数让我们模拟了各种各样的 图案。例如,查看Lisp中的map函数。它 表示程序员需要做某事的模式 列表中的每个元素。那个“东西”被编码为一个函数和 作为参数传递给map。

正如我们所看到的,FP最显着的特征是它的副作用 游离度。如果函数执行的不仅仅是计算值 从它的输入,然后它导致副作用。这样的功能是 不允许使用纯FP。很容易测试无副作用的功能。 在运行测试之前没有设置全局状态 运行测试后没有要检查的全局状态。每个功能都可以 只需提供输入并检查即可独立测试 回报价值。这样可以轻松编写自动化测试。另一个 副作用自由度的优点是它可以让你更好地控制 关于并行性。

许多FP语言正确处理递归和迭代。他们这样做 支持称为尾递归的东西。尾递归是什么 - 如果一个函数调用它自己,它就是它做的最后一件事 立即删除当前堆栈帧。换句话说,如果一个 函数尾递归1000次,它不会增长 堆栈1000深。这使得特殊的循环结构 这些语言不必要。

Lambda Calculus是FP语言中最简化的版本。 像Haskell这样的高级FP语言被编译为Lambda 结石。它只有三个句法结构但仍然是 表达足以表示任何抽象或算法。

我认为FP应该被视为一种元范式。我们可以 使用简单的方式编写任何风格的程序,包括OOP Lambda微积分提供的功能抽象。

谢谢, - 维杰

原始讨论链接:http://groups.google.co.in/group/bangalore-fp/browse_thread/thread/4c2cfa7985d7eab3

答案 4 :(得分:3)

抽象,通过参数化表达式的某些部分来创建函数的过程。

应用程序,通过用特定值替换其参数来评估函数的过程。

在某种程度上,这就是它的全部内容。

答案 5 :(得分:0)

尽管这个问题比较老,但还是想分享我的观点作为参考。

    FP中的
  • 核心概念是“ 功能
  • FP提供了KISS(Keep It Simple Sxxxxx)编程范例(一旦您有了FP的构想,您就会开始讨厌OO范例)
  • 这是我与OO设计模式的简单FP比较。我的见解FP是我的观点,如果与实际存在任何差异,请纠正我。

    enter image description here