到目前为止,我主要接触过OO编程,并期待学习一种功能语言。我的问题是:
- 什么时候选择函数编程而不是面向对象?
- 函数编程是更好的选择,典型的问题定义是什么?
到目前为止,我主要接触过OO编程,并期待学习一种功能语言。我的问题是:
Answers:
什么时候选择功能编程而不是面向对象?
当您预计会有另一种软件演变时:
当您对事物进行固定的操作时,面向对象的语言非常有用,并且随着代码的发展,您主要添加新的事物。这可以通过添加实现现有方法的新类来完成,而现有类则不理会。
当您拥有固定的事物集时,功能语言是很好的选择 ,并且随着代码的发展,您主要在现有事物上添加新的操作。这可以通过添加使用现有数据类型进行计算的新函数来完成,而现有函数则不予考虑。
当进化走错路时,您就会遇到问题:
向面向对象的程序添加新操作可能需要编辑许多类定义以添加新方法。
向功能程序中添加新事物可能需要编辑许多功能定义以添加新案例。
这个问题已经众所周知很多年了。1998年,菲尔·沃德勒(Phil Wadler)将其称为“表达问题”。尽管一些研究人员认为表达问题可以通过混合函数之类的语言功能解决,但尚未得到广泛接受的解决方案成为主流。
函数编程是更好的选择,典型的问题定义是什么?
功能语言擅长以树形形式处理符号数据。最喜欢的例子就是编译器,在源和中间语言改变很少(几乎相同的事情),但是编译器作者一直在增加新的翻译和代码改进或优化(对事物的新操作)。编译和翻译通常是功能语言的“杀手级应用”。
您不必在两个范式之间进行选择。您可以使用许多功能概念来编写具有OO体系结构的软件。FP和OOP本质上是正交的。
以C#为例。您可以说这主要是面向对象的,但是有许多FP概念和构造。如果您考虑使用Linq,则允许Linq存在的最重要的构造实际上是功能性的:lambda表达式。
另一个示例F#。您可以说它主要是FP,但是有许多OOP概念和构造可用。您可以定义类,抽象类,接口,处理继承。当可变性使您的代码更清晰或极大地提高性能时,您甚至可以使用可变性。
许多现代语言是多种范例。
因为我在同一条船上(OOP背景,学习FP),所以建议您阅读一些我非常赞赏的读物:
日常.NET开发的函数式编程,作者Jeremy Miller。一篇很棒的文章(尽管格式不佳)展示了C#上FP的许多技术和实际示例。
现实世界中的函数式编程,作者:Tomas Petricek。一本很棒的书,主要涉及FP概念,试图解释什么是何时使用。F#和C#中都有很多示例。另外, Petricek的博客是一个很好的信息来源。
面向对象编程提供:
在Haskell或Scala中,函数式编程可以通过类型类的更通用机制进行替换。不鼓励或禁止使用可变的内部状态。内部表示的封装也可以实现。参见Haskell与OOP进行比较。
诺曼的断言“在功能程序中添加新事物可能需要编辑许多功能定义以添加新案例”。取决于功能代码使用类型类的程度。如果将特定抽象数据类型上的模式匹配分布在整个代码库中,则您确实会遭受此问题的困扰,但是从一开始它可能是一个较差的设计。
编辑讨论类型类时删除对隐式转换的引用。在Scala中,类型类是使用隐式参数而不是转换进行编码的,尽管隐式转换是实现兼容类型替换的另一种方法。