我一直认为函数式编程可以用Python完成。因此,我很惊讶Python在this问题中没有提及,当提到它时,它通常不是很积极。然而,没有给出很多理由(没有提到模式匹配和代数数据类型)。所以我的问题是:为什么Python不适合函数式编程?是否有更多的原因,而不是缺乏模式匹配和代数数据类型?或者这些概念对函数式编程如此重要,以至于不支持它们的语言只能被归类为二级函数式编程语言? (请记住,我在函数式编程方面的经验非常有限。)
答案 0 :(得分:377)
您提到的问题是哪种语言可以促进面向对象和函数式编程。 Python没有提升函数式编程,即使工作也相当不错。
在Python中反对函数式编程的最佳参数是,Guido仔细考虑了命令式/ OO用例,而函数式编程用例则没有。当我编写命令式Python时,它是我所知道的最漂亮的语言之一。当我编写功能性Python时,它变得像普通语言一样丑陋和令人不快,没有BDFL。
这并不是说它很糟糕,只是你必须比你改用一种促进函数式编程或转而编写OO Python的语言更加努力工作。
以下是我在Python中遗漏的功能性内容:
list
。 (迭代器使用一次)答案 1 :(得分:97)
Guido对此here有一个很好的解释。这是最相关的部分:
我从来没有考虑过Python 受功能影响很大 语言,无论人们说什么 或者想一想。我更熟悉了 使用命令式语言,例如C. 和Algol 68虽然我做了 函数一流的对象,我 没有将Python视为功能性的 编程语言。但是,早些时候 很明显,用户想要 使用列表和函数做更多事情。
...
值得注意的是,甚至 虽然我没想到Python是一个 功能语言,介绍 封闭已经有用了 许多其他先进的发展 编程功能。例如, 新式课程的某些方面, 装饰器等现代功能 依靠这种能力。
最后,即使是一些 功能编程功能有 多年来一直在推出Python 仍然缺乏某些功能 “真正的”功能编程 语言。例如,Python可以 不执行某些类型的 优化(例如,尾递归)。 一般来说,因为Python非常 动态性,这是不可能的 那种编译时优化 从函数式语言中得知 Haskell或ML。那没关系。
我从中提取了两件事:
答案 2 :(得分:50)
Scheme没有代数数据类型或模式匹配,但它肯定是一种函数式语言。从函数式编程的角度来看,有关Python的烦人事情:
残废的Lambdas。由于Lambdas只能包含一个表达式,并且您无法在表达式上下文中轻松完成所有操作,这意味着您可以“即时”定义的函数是有限的。
如果是陈述,而不是表达。这意味着,除其他外,你不能在里面有一个带有if的lambda。 (这在Python 2.5中由三元组修复,但看起来很难看。)
Guido每隔一段时间威胁remove map, filter, and reduce
另一方面,python有词法闭包,Lambdas和列表推导(无论Guido是否认可,它都是一个“功能性”概念)。我在Python中做了很多“函数式”编程,但我很难说它是理想的。
答案 3 :(得分:21)
我永远不会把Python称为“功能性”,但每当我使用Python编程时,代码总是几乎完全是功能性的。
不可否认,这主要归功于非常好的列表理解。所以我不一定会建议Python作为函数式编程语言,但我建议使用Python的任何人进行函数式编程。
答案 4 :(得分:16)
让我演示一段代码,该代码取自SO上的“功能性”Python question的答案
的Python:
def grandKids(generation, kidsFunc, val):
layer = [val]
for i in xrange(generation):
layer = itertools.chain.from_iterable(itertools.imap(kidsFunc, layer))
return layer
Haskell中:
grandKids generation kidsFunc val =
iterate (concatMap kidsFunc) [val] !! generation
这里的主要区别是Haskell的标准库具有函数式编程的有用功能:在这种情况下iterate
,concat
和(!!)
答案 5 :(得分:14)
对于这个问题(以及答案)而言,一件非常重要的事情如下: 什么是函数式编程,它最重要的属性是什么。 我会尝试提出自己的观点:
函数式编程就像在白板上编写数学一样。当你写方程时 在白板上,你不会考虑执行命令。 (通常)没有突变。 你不会在第二天回来看看它,当你再次进行计算时, 你会得到不同的结果(或者,如果你有一些新鲜的咖啡,你也许可以:))。基本上, 董事会上有什么,当你开始写作时答案已经存在 事情发生了,你还没有意识到它是什么。
功能编程非常类似;你不改变事情,你只是评价 等式(或在这种情况下,“程序”)并找出答案是什么。该程序 还在那里,没有修改。与数据相同。
我会将以下内容列为函数式编程的最重要特性: a)引用透明度 - 如果您在其他时间评估相同的语句 和地方,但具有相同的变量值,它仍然意味着相同。 b)没有副作用 - 无论你盯着白板多久,等式都是另一个 看着另一块白板的家伙不会不小心改变。 c)功能也是值。可以传递给其他人,也可以传给他人 变量。 d)函数组合,你可以做h = g·f,从而定义一个新的函数h(..) 相当于调用g(f(..))。
此列表按我的优先顺序排列,因此参考透明度是最重要的, 然后没有副作用。
现在,如果你通过python并检查语言和库支持的程度, 和保证,这些方面 - 然后你就可以回答你自己的问题了。
答案 6 :(得分:11)
Python几乎是一种功能语言。它是“功能性精简版”。
它有额外的功能,所以对某些人来说它不够纯粹。
它也缺少一些功能,所以对某些人来说还不够完整。
缺少的功能相对容易编写。在Python中查看关于FP的this等帖子。
答案 7 :(得分:8)
上面没有提到的另一个原因是内置类型的许多内置函数和方法修改了一个对象但是没有返回修改后的对象。功能代码更清晰,更简洁。例如,如果some_list.append(some_object)返回了some_list并附加了some_object。
答案 8 :(得分:4)
除了其他答案之外,Python和大多数其他多范式语言不适合真正的函数式编程的一个原因是因为它们的编译器/虚拟机/运行时不支持功能优化。这种优化是通过编译器理解数学规则来实现的。例如,许多编程语言支持map
函数或方法。这是一个相当标准的函数,它将函数作为一个参数,迭代作为第二个参数,然后将该函数应用于iterable中的每个元素。
无论如何,map( foo() , x ) * map( foo(), y )
与map( foo(), x * y )
相同。后一种情况实际上比前者更快,因为前者执行两个副本,后者执行一个副本。
更好的函数式语言可识别这些基于数学的关系并自动执行优化。不专用于功能范例的语言可能不会优化。