“函数式编程”有明确的含义,但“函数式语言”呢?
Posted
技术标签:
【中文标题】“函数式编程”有明确的含义,但“函数式语言”呢?【英文标题】:"Functional programming" has a clear meaning, but does "functional language"? 【发布时间】:2011-01-18 12:04:52 【问题描述】:我非常清楚函数式和命令式编程技术之间的区别。但是有一种普遍的趋势是谈论“函数式语言”,这真的让我很困惑。
当然,像 Haskell 之类的一些语言比 C 等其他语言更适合函数式编程。但即使是前者也可以进行 I/O(它只是把它放在一个贫民窟中)。而且您可以用 C 编写函数式程序(这简直是荒谬的难)。所以也许这只是程度的问题。
不过,即使在程度上,有人称 Scheme 为“函数式语言”是什么意思?我看到的大多数 Scheme 代码都是必要的。如果您愿意,Scheme 是否可以很容易地以函数式风格编写? Lua 和 Python 也是如此。它们也是“函数式语言”吗?
我(真的)不想成为一名语言警察。如果这只是一种松散的谈话方式,那很好。我只是想弄清楚它是否确实有一些我没有看到的明确含义(即使是程度问题)。
【问题讨论】:
实际上,我希望玩 Perl/Python/Ruby/C# 的孩子们在他们作为代码生成的一堆难看的冒着热气的标点符号中出现匿名函数时,就停止标记他们的问题functional-programming
例子。我对他们的问题不感兴趣,但我感兴趣的一些问题只有functional-programming
标签来区分它们。正如您所指出的,它应该是功能语言,但没有人使用该标签。
@Pascal - 我完全不同意。有很多函数式编程技术在各种不是“纯函数式语言”的语言中都很有用。这与使用允许多种范式的语言以面向对象的方式进行编程相同。如果您对纯函数式语言感兴趣,那么也许应该有一个单独的标签......或者通过这些特定语言的标签查找内容。
说到面向对象编程,如果你觉得这里的 Pascal 不开心,去找一些 Smalltalkers 问问他们 C++ 是否“支持面向对象编程”。
@Pascal:虽然您可能对函数式编程的一些更复杂的方面感兴趣,但人们仍在尝试理解许多更简单的元素(例如折叠)。我阅读了函数式编程标签以进一步了解函数式编程的知识,因为我发现它是一种非常有用的风格,但我不使用任何纯/传统的函数式语言。我只是碰巧看到了函数式编程的特定元素为整个过程带来的许多好处(一个大的好处是更容易自动化测试)。
@PascalCuoq 将其他语言的程序员描述为“孩子们在玩”,并将他们的代码描述为热气腾腾的一堆,这不是很优雅(而且有点粗俗)。
【参考方案1】:
我会说函数式语言是任何允许函数式编程而没有过度痛苦的语言。
【讨论】:
【参考方案2】:一种促进函数式编程的语言(和平台),作为充分利用所述平台功能的一种手段。
【讨论】:
【参考方案3】:一种语言使得创建具有副作用的函数比没有副作用的函数更难。可变/不可变数据结构也是如此。
【讨论】:
【参考方案4】:您可以使用任何语言进行函数式编程。我尽可能地尝试。
Python、Linq 都提倡函数式编程。
像 Haskell 这样的纯函数式语言要求您使用数学函数进行所有计算,这些函数不会修改任何内容,它们只是返回值。
此外,函数式语言通常允许您编写高阶函数、将函数作为参数和/或返回类型的函数。
【讨论】:
我很确定 Lisp 不是那种意义上的纯函数式语言。您可以修改变量的值。 大多数 Lisps 并不纯正。 Common Lisp 和 Scheme 都不是。 Clojure 是我唯一能想到的纯 Lisp。 除此之外,还可以在 haskell 中编写“命令式”代码。但是在世界的 Haskell 模型中,状态从一个语句传递到另一个语句。 Lisp 不是纯函数式语言。在 lisp 中执行 IO 并非没有副作用。编写带有副作用的闭包也是完全可能的。 Python如何促进函数式编程? Lambda 函数绝对是二等公民,默认情况下一切都是可变的。甚至 Guido 也同意 Python 不是一种函数式语言:python-history.blogspot.com/2009/04/…【参考方案5】:我认为关于“OOP 语言”可以问同样的问题。毕竟,您可以用 C 编写面向对象的程序(这样做并不少见)。但是 C 没有任何内置的语言结构来启用 OOP。您必须在没有编译器太多帮助的情况下“手动”执行 OOP。这就是为什么它通常不被视为 OOP 语言的原因。我认为这种区别也可以应用于“函数式语言”:例如,用 C++ 编写函数式代码并不少见(想想像 std::count_if
或 std::transform
这样的 STL 函数)。但是 C++(目前)缺乏支持函数式编程的内置语言特性,比如 lambdas。 (为了论证,我们忽略 boost::lambda。)
所以,为了回答你的问题,我想说的是,尽管可以用以下每种语言编写函数程序:
C 不是函数式语言(没有内置的函数式语言结构) Scheme、Python 和其他朋友都有函数式构造,因此它们是函数式语言。但它们也具有命令式和 OOP 结构,因此它们通常被称为“多范式”语言。【讨论】:
【参考方案6】:Jane Street 的 Brian Hurt 不久前为此写了 very good article。他得出的基本定义是,函数式编程语言是一种模拟 lambda 演算的语言。想想哪些语言被广泛认为是功能性的,你会发现这是一个非常实用的定义。
Lisp 是对 lambda 演算建模的原始尝试,因此它符合这个定义——尽管由于大多数实现并没有非常接近 lambda 演算的思想,它们通常被认为是混合范式或充其量是功能较弱。
这也是为什么很多人对诸如 Python 之类的语言被称为函数式感到愤怒的原因。 Python 的一般哲学与 lambda 演算无关——它根本不鼓励这种思维方式——所以它不是一种函数式语言。它是具有一流功能的图灵机。您可以在 Python 中进行函数式编程,是的,但是该语言的根源与函数式语言所做的数学不同。 (顺便提一下,Guido van Rossum 本人agrees with this description of the language。)
【讨论】:
当然,如果我编写一种模拟 SKI 演算的语言,它仍然可以正常工作。是的,这可以与(无类型的)lambda 演算互译。但是任何图灵完备的语言也是如此。 @profjim:SKI 演算本身是基于 lambda 演算的,所以是的,基于它的语言将基于 lambda 演算。确实,lambda 演算是图灵等效的,但是这两个模型与人类理解的水平有很大不同,这是编程语言工作的领域。你的反对就像注意到汽车和船都是由相似的原子,所以它们之间不可能有任何有效的区别——在某些层面上确实如此,但在我们通常处理的那个层面上却不是。 也许它是这样介绍给你的,但历史上它是独立开发的(我认为更早)。我同意在某种直观意义上,它们 看起来 比 C 中的任何一种都更相似,并且在一种情况下翻译模式比另一种情况更短。但我认为没有什么比这更重要的了。我并不是说任何事物之间没有有效的区别,我是说既然还有船,为什么还要用“汽车模型”来定义“交通方式”。 profjim 是正确的,由 Schönfinkel 发明并由 Curry 开发的组合逻辑比 Church 的 λ 微积分早了十年左右。组合微积分方法背后的动机是构建形式逻辑而不需要量化变量。一些组合子基允许通用计算是无意的(也许令人沮丧,因为图灵完备性大致等同于不一致的逻辑)。【参考方案7】:我喜欢@Randolpho 的回答。关于功能,我可以在这里引用列表:
Defining point of functional programming
即
纯度(又名不变性,避免副作用,参照透明) 高阶函数(例如,将函数作为参数传递,将其作为结果返回,将匿名函数动态定义为 lambda 表达式) 懒惰(又名非严格评估,与纯度相结合时最有用/可用) 代数数据类型和模式匹配 关闭 柯里化 / 部分应用 参数多态性(又名泛型) 递归(由于纯粹性而更加突出) 使用表达式而不是语句进行编程(同样,从纯粹性出发)一种特定编程语言的语法和结构越适合使上面列出的各种 FP 功能易于/轻松地表达和实现,就越有可能有人将其标记为“函数式语言”。
【讨论】:
愿意接受这个答案和 Norman Ramsey 的组合。我应该只编辑和合并它们吗?【参考方案8】:Haskell 对于有副作用的函数和没有副作用的函数有不同的类型。
对于 100% 函数式语言来说,这是一个非常好的区分属性,至少恕我直言。
【讨论】:
【参考方案9】:在以学习编程语言为生的人中,“函数式编程语言”是一个很弱的术语。有一个强烈的共识是:
任何自称为函数式的语言都必须支持first-class,具有词法范围规则的嵌套函数。相当一部分人还将“功能语言”一词保留用于以下语言:
纯(或无副作用,referentially transparent,see also)就像在 Agda、Clean、Coq 和 Haskell 等语言中一样。
除此之外,什么是函数式编程语言通常是意图的问题,即设计师是否希望将其称为“函数式”。 p>
Perl 和 Smalltalk 是支持一流函数但其设计者不称它们为函数式的语言示例。 Objective Caml 是一种称为函数式语言的示例,尽管它具有完整的对象系统,具有继承性和一切。
被称为“功能性”的语言将倾向于具有以下特征(取自Defining point of functional programming):
匿名函数(lambda 表达式) 递归(由于纯粹性而更加突出) 使用表达式而不是语句进行编程(同样,从纯粹性出发) 关闭 柯里化 / 部分应用 Lazy evaluation Algebraic data types 和 模式匹配 Parametric polymorphism(又名泛型)一种特定的编程语言的语法和结构越适合使上面列出的各种编程功能易于/轻松地表达和实现,就越有可能有人将其标记为“函数式语言”。
【讨论】:
愿意接受这个答案和布赖恩的组合。我应该只编辑和合并它们吗? @profjim:鉴于布赖恩的答案是重复的,最好将其链接起来。或者,如果您觉得在这里复制信息是值得的,那就去吧。无论哪种方式,编辑直到你满意为止:-)【参考方案10】:我曾经写过一篇(相当长的)分析,为什么“函数式编程语言”这个词没有意义,也试图解释为什么 Haskell 中的“函数”与 Lisp 或 Python 中的“函数”完全不同:@987654321 @
诸如“地图”或“过滤器”之类的东西在很大程度上也可以在 C 中实现。
【讨论】:
以上是关于“函数式编程”有明确的含义,但“函数式语言”呢?的主要内容,如果未能解决你的问题,请参考以下文章