混合面向对象和函数式编程

Posted

技术标签:

【中文标题】混合面向对象和函数式编程【英文标题】:Mixing object-oriented and functional programming 【发布时间】:2010-11-04 04:13:18 【问题描述】:

有哪些语言可以同时促进面向对象和函数式编程?我知道任何支持一流函数的语言都可以被认为是函数式的,但我正在寻找一种专门针对这两种编码风格的语法。

使用这样的语言,我想象将所有状态更改隔离到单个代码部分,并让程序的其余部分纯粹是功能性的。光是想想就让我流口水(调试天堂!)。

到目前为止,我已经发现了Scala,尽管我只是听说过它(而且看起来很神奇)。在这种“混合风格”范式中有什么大的竞争者吗?

【问题讨论】:

我不太喜欢这样混合的语言。它破坏了我的观点。我现在正在学习 Haskell,然后我将深入研究 Clojure。我最喜欢的两种语言! :D 我用过 Clojure,对于前 Lisper 来说非常棒!我可能会和你相反,然后学习 Haskell。 +1 我完全同意将状态更改隔离到程序的专用部分并使其在其他地方起作用(或相反;肯特贝克称它们为“数学微世界”)的想法. 【参考方案1】:

javascript:OO 和 functional。

【讨论】:

而使用 Coffeescript 让功能体验更佳。【参考方案2】:

最著名的是OCaml 和F#(可以模糊地描述为 .NET 的 OCaml)。

还有许多其他多范式语言,例如Oz,但它们主要具有教学价值。相比之下,OCaml 非常实用。它几乎和 C 一样快,几乎和 Haskell 一样漂亮:)

Python 和 Ruby 等流行的脚本语言也可以让您以函数式风格进行编程。但是,它们没有提供“经典”函数式语言(以及 OCaml)所具有的最强大的功能之一:pattern matching(不要误认为是正则表达式)。

【讨论】:

OCaml 和 F# 在语法方面肯定几乎和 Haskell 一样漂亮,但它们不允许您抽象类型构造函数(没有更高种类的类型)。 Scala 不是很漂亮,但它确实为您提供了更高的种类。如果您只想编写更漂亮的代码,那很好,但如果您想要更强大的抽象,Caml 变体将无法实现。【参考方案3】: OCaml O'Haskell(和object oriented programming is somewhat possible even in normal Haskell) Nemerle 可能是newLISP

此外,Python、Ruby、Lua 等许多脚本语言都具有此功能,但缺少函数式语言的许多优秀特性,例如代数数据类型和模式匹配。

【讨论】:

【参考方案4】:

Haskell:纯函数式,几乎没有 OO,但继续前进吧。 :D

Scala:OO 和 FP 的完美结合,可能在 10 年或 2 年内超过 java 成为 JVM 上的主要语言。我喜欢它,因为它为 java 平台带来了函数式编程,这就是非常需要恕我直言。

C#:对 OO 的出色支持,以及更多功能(已经是一流的功能,我们将看看 .net 4 带来了哪些改进)

F#:.net 语言专为功能而构建,与 C# 不同,C# 最初是为 OO 设计的。

Python:非常适合 OO,但 not at all suited to FP

Javascript:支持一流的函数,但不是专门为 Scala 和 F# 等 FP 设计的。还是比 python 恕我直言。

为什么要混合使用 OO 和 FP?作为垫脚石?

【讨论】:

为什么要混合使用 OO 和 FP? - 因为这就是我们的世界。有些方面很好地用永恒的关系建模,其他方面需要生命周期和状态。【参考方案5】:

据我所知,OCaml 和 F# 是最流行的混合 OOP 和 FP 的语言。

大多数语言,如 Ruby,都混合了函数式编程,但很多人甚至没有意识到这一点。我发现这样的语言在语法方面还有很多不足之处。

【讨论】:

【参考方案6】:

C#。它是命令式的,可以很方便,但也有很多功能特性。 Lambda、迭代器和 LINQ 都是函数式的。

它可能对纯粹主义者没有太大吸引力,但它对我有用。

【讨论】:

最后一部分是我的一个笑话。一般来说,我不是“purisim”的人。显然,虽然有些人冒犯了。 我并不想冒犯任何人。 我不觉得它冒犯(对任何人),但这吸引了一些“冒犯性”选票;我建议你重新措辞最后一点。这是相当可悲的(不是斯科特,而是“冒犯”的一部分),因为这篇文章显然不是“冒犯性的”。但我们在那里。【参考方案7】:

JavaScript、Python 和 Ruby 可以通过这种方式使用,但 Scala 通过静态键入函数并在 JVM 下工作,提高了一个档次。

【讨论】:

为什么有人会使用 Python 来学习函数式编程? :\【参考方案8】:

你真的问错问题了。您的问题的前提是“OO”和“功能”编程之间存在区别。这种区别既不有趣也不相关。事实上,按照“支持一流功能”的标准,甚至Java is functional。

但是你用“纯粹的功能”一针见血。这是有趣的一点。哪些语言可以为您提供这样的参考透明度和纯度?嗯,他们中的大多数,如果你非常小心的话。但实际上并没有多少人能保证你的函数是纯的。我只能想到几种可以为您提供这种功能的语言。

其中之一是 Haskell。在 Haskell 中,您编写的程序从头到尾都是纯函数式的。副作用被委托给称为 IO 的数据结构,状态通过纯函数传递或封装在 monad 中来处理。因此,您拥有了您的“调试天堂”,其中只有一小部分代码与全局状态交互,而程序的其余部分是纯的,并且纯由语言强制执行。

【讨论】:

我对纯度的关注不如对可读性的关注。我知道许多语言支持许多编程风格,但一种语言的语法在很大程度上决定了哪种风格被广泛接受。我认为 Scala 是我见过的第一个说“我们正在尝试两者兼得!” -1,因为他是学霸,而不是真正回答问题。【参考方案9】:

只要你不坚持“纯粹”,Common Lisp 就能满足你的所有需求。

【讨论】:

除非你需要静态类型检查。 我对静态和动态类型持怀疑态度。我个人喜欢 Clojure 和 Haskell。 好吧,静态类型和真正的面向对象是矛盾的。你不可能拥有一切。 将近 2 年后重新审视这个问题:静态类型和动态类型并不相互排斥。没有人会阻止您在编译时推断和检查类型,这就是大多数现代 Common Lisp 实现所做的(也支持程序员的声明)。动态类型只是意味着你也有一个在运行时工作的类型系统。【参考方案10】:

Python、javascript、common lisp、ruby、smalltalk、haskell 和 ocaml,我想都没想。这并不是一个真正的异国情调的组合。

【讨论】:

【参考方案11】:

我想知道您为什么要寻找一种特别鼓励混合使用的语言,而不是仅仅使用一种能够很好地进行函数式编程和 OO 编程的语言?它可以通过 Python、Ruby、Perl 或类似的解释语言轻松实现。此外,基于 C 的 OO 语言倾向于将纯 C 与 OO 特性混合在一起,例如,如果您选择,Objective C 可以很容易地以这种方式编写。

编辑:我已经知道我是不正确的,我在这里留下了这个答案,以防有人可以从我的错误中吸取教训 - 请参阅 cmets。

【讨论】:

因为尝试使用 Python 之类的语言进行函数式编程,就像尝试用一把剪刀修剪 10 英亩的土地。 是的,公平交易,可以做到,但它不是理想的方法。我仍然不确定 C 扩展是否是一个坏主意,我对 c++ 不太熟悉,但在目标 c 中做这样的事情的想法似乎并不那么糟糕。如果您愿意,您可以根据自己的内心内容编写函数式 C 并使用对象,我不明白为什么 c++ 不会轻易做到这一点。我想我的愚蠢可能让我失明;) C 或 Objective-C 的功能如何? 在阅读了一些关于 haskell 的文章后,现在对函数式的含义有了一些了解。 托比,也许你在想像 C 或 Pascal 那样的“程序化”。我可以看到它是如何与“功能性”混淆的。【参考方案12】:

根据我的经验,C# 非常适合此目的。 在 c# 中,你可以委托函数,甚至使用扩展方法,你可以模仿 OOP 行为,但要考虑 FP。

我通常构建一个具有我需要的行为的类,然后构建一些函数来围绕它使用 FP 实践来完成我的肮脏工作,并且效果很好,正如你提到的调试天堂。

在我看来,Pure FP 和 Pure OOP 都带来了一些其他人不会的缺点。 OOP 往往会使代码复杂化,而 FP 使某些企业更难编写代码,尤其是在状态至关重要的时候。

【讨论】:

【参考方案13】:

鲁比!在 Ruby 中,一切都是对象(甚至是字面量),并且它还具有完整的函数式编程支持。

【讨论】:

作为对象的一切都不一定是 OOP,是吗?在 JavaScript 中,几乎所有东西都是一个对象(包括函数,所以你可以做一些函数式编程的东西)。 OO 与类无关。许多 OO 语言没有类:Smalltalk-71(毕竟,这是发明“OO”一词的语言)、Self、Io、Ioke、ECMAScript(又名 JavaScript)、NewtonScript。 Alan Kay 明确表示他认为向 Smalltalk 添加类是一个错误,并且由于他发明“面向对象”一词,我们甚至可以说具有类的语言不是 OO! 我认为 Alan Kay 无法再决定 OO 是什么,什么不是。我确实在***上找到了这个:“阿姆斯特朗,面向对象开发的夸克。按照流行度的降序排列,“夸克”是:继承、对象、类、封装、方法、消息传递、多态、抽象' 根据该列表,Self(有史以来种面向对象的语言之一)、Simula(有史以来第一个 OO 语言)、Smalltalk-71(用于OO 一词的发明),JavaScript、Io、Ioke 和 NewtonScript 不是 OO,因为它们没有类。 C++、Java、C# 不是面向对象的,因为它们没有消息传递。 CLOS 和 Eiffel 不是 OO,因为它们没有方法。事实上,除了 Oz 之外,今天存在的 no 语言具有这些特征。您是在声称 Oz 是唯一的 OO 语言吗? 另外,Alan Kay 发明了“面向对象”一词。因此,他可以决定这意味着什么。如果您想发明自己的术语,那很好,那么您可以将其定义为您想要的任何含义。但随意重新定义定义明确、广泛使用的技术术语不是一个好主意,因为它几乎不可能进行有意义的讨论。

以上是关于混合面向对象和函数式编程的主要内容,如果未能解决你的问题,请参考以下文章

函数式编程与面向对象编程[3]:Scala的OOP-FP混合式编程与抽象代数理论

Python 函数式编程和面向对象编程

函数式编程和面向对象编程

《JavaScript函数式编程思想》——从面向对象到函数式编程

python编程:函数式编程和面向对象编程的对比

为什么说面向对象编程和函数式编程都有问题