协慌网

登录 贡献 社区

功能编程与面向对象编程

到目前为止,我已经主要接触过 OO 编程,并期待学习一门函数式语言。我的问题是:

  • 什么时候选择面向对象的函数式编程?
  • 什么是典型的问题定义,函数式编程是更好的选择?

答案

什么时候选择面向对象的函数式编程?

当您预期不同类型的软件演变时:

  • 当你对事物有一套固定的操作时,面向对象的语言是很好的,随着代码的发展,你主要添加新东西。这可以通过添加实现现有方法的新类来完成,并且现有类保持不变。

  • 当你有一套固定的东西时 ,函数式语言是很好的,随着代码的发展,你主要在现有的东西上添加新的操作 。这可以通过添加使用现有数据类型计算的新函数来实现,并且现有函数是独立的。

当进化走错路时,你会遇到问题:

  • 向面向对象的程序添加新操作可能需要编辑许多类定义以添加新方法。

  • 在功能程序中添加新类型的东西可能需要编辑许多函数定义来添加新案例。

这个问题多年来一直众所周知; 1998 年, Phil Wadler 将其称为 “表达问题” 。虽然一些研究人员认为表达问题可以通过 mixins 这样的语言特性来解决,但是一种被广泛接受的解决方案尚未成为主流。

什么是典型的问题定义,函数式编程是更好的选择?

功能语言擅长以树形式操纵符号数据。最喜欢的例子就是编译器,在源和中间语言改变很少(几乎相同的事情 ),但是编译器作者一直在增加新的翻译和代码改进或优化(对事物的新操作)。编译和翻译更一般地是功能语言的 “杀手级应用”。

您不一定要在两种范例之间进行选择。您可以使用许多功能概念编写具有 OO 架构的软件。 FP 和 OOP 本质上是正交的

以 C#为例。你可以说它主要是 OOP,但有许多 FP 概念和结构。如果考虑Linq ,允许 Linq 存在的最重要的构造本质上是功能性的: lambda 表达式

另一个例子,F#。你可以说它主要是 FP,但有许多 OOP 概念和结构可用。您可以定义类,抽象类,接口,处理继承。您甚至可以在使代码更清晰或显着提高性能时使用可变性。

许多现代语言都是多范式的。

推荐读物

因为我在同一条船上(OOP 背景,学习 FP),我建议你读一些我真的很感激:

  • Jeremy Miller 为日常. NET 开发提供的功能编程 。一篇很棒的文章(虽然格式很差),展示了 C#上 FP 的许多技术和实际的实际例子。

  • 真实世界的功能编程 ,由 Tomas Petricek 撰写。一本伟大的书,主要涉及 FP 概念,试图解释它们是什么,什么时候应该使用它们。 F#和 C#都有很多例子。此外, Petricek 的博客是一个很好的信息来源。

面向对象编程提供:

  1. 封装,到
    • 控制内部状态的突变
    • 限制耦合到内部表示
  2. 子类型,允许:
    • 替换兼容类型(多态)
    • 在类之间共享实现的粗略方法(实现继承)

Haskell 甚至 Scala 中的函数式编程可以允许通过类型类的更通用机制进行替换。不鼓励或禁止可变的内部状态。还可以实现内部表示的封装。有关比较,请参阅Haskell 与 OOP

Norman 断言 “在功能程序中添加新东西可能需要编辑许多函数定义来添加新案例”。取决于功能代码使用类型类的程度。如果特定抽象数据类型上的模式匹配遍布整个代码库,您确实会遇到这个问题,但它可能是一个糟糕的设计。

EDITED在讨论类型类时删除了对隐式转换的引用。在 Scala 中,类型类使用隐式参数进行编码,而不是转换,尽管隐式转换是实现兼容类型替换的另一种方法。