在面向对象的编程中,我们可以说核心概念是:
函数式编程会是什么?
答案 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
简而言之,
答案 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)