函数式编程与面向对象编程[关闭]

     2023-02-23     213

关键词:

【中文标题】函数式编程与面向对象编程[关闭]【英文标题】:Functional programming vs Object Oriented programming [closed] 【发布时间】:2011-01-05 22:39:56 【问题描述】:

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

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

【问题讨论】:

复制:***.com/questions/552336/… 这是相关的programmers.stackexchange.com/questions/9730/… 类似的问题 cs.se 也关闭了what is example where functional programming gives better results than imperative style。传统观点似乎是一个并不优于另一个,或者它们在简单的标准上不可比较,或者它们用于不同的目的......函数式编程具有更多的科学/学术起源和用途,并且在工业中不太常见,所以这个问题也建立了一个“行业与学术界”无法解决的 pov/冲突。一个在函数式编程中展示 OOP 风格的经典参考,SICP 书/麻省理工学院 "OO 通过封装移动部件使代码易于理解。FP 通过最小化移动部件使代码易于理解。" --Micheal Feathers,2010 年 【参考方案1】:

你什么时候选择函数式编程而不是面向对象?

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

当您对事物 有一组固定的操作 时,面向对象的语言是很好的,并且随着代码的发展,您主要是添加新事物。这可以通过添加实现现有方法的新类来完成,而现有的类将被单独保留。

当您拥有一组固定的事物时,函数式语言是很好的,并且随着代码的发展,您主要在现有事物上添加新的操作。这可以通过添加使用现有数据类型进行计算的新函数来实现,而现有函数则不受影响。

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

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

向函数式程序添加新事物可能需要编辑许多函数定义以添加新案例。

这个问题已经众所周知很多年了; 1998 年,Phil Wadler dubbed it the "expression problem"。尽管一些研究人员认为表达问题可以通过 mixins 等语言特性来解决,但广泛接受的解决方案尚未成为主流。

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

函数式语言擅长以树状形式处理符号数据。一个最喜欢的例子是编译器,其中源语言和中间语言很少更改(大部分是相同的事物),但编译器编写者总是添加新的翻译和代码改进或优化(事物的新操作)。编译和翻译通常是函数式语言的“杀手级应用”。

【讨论】:

这个答案背后有一些严肃的禅意。我认为它阐明了一个事实,即某些 OOP 设计模式(访问者)实际上是试图克服添加新操作问题的黑客。 在 JavaScript 中,你可以拥有所有的东西。 @ErikReppen 什么时候出现问题,你什么时候选择使用功能特性,什么时候选择使用面向对象特性? @NormanRamsey 在 JS 中混用它并不少见,一流的功能与许多 JS OOP 相关的功能相关联。 JS 的数组排序将函数作为 arg,可以产生一些强大的数据结构。闭包 + 传递函数用于保持 jquery 对象非常轻量级的内存,因为大多数方法只是引用。等等…… @NormanRamsey:非常好的答案,与 SICP 一致。根据这种分类,函数式编程和过程式编程在面向对象编程的对立面被归为一类。这可以解释 OOP 在 1980 年代末 1990 年代初的繁荣:当 GUI 成为主流时,OOP 被证明是对其建模的好方法,因为您通常有一组固定的操作(绘制、打开、关闭、调整大小)以及越来越多的小部件。当然,这并不意味着 OOP 对于任何应用程序都比程序性更好,正如您所说明的那样。【参考方案2】:

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

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

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

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

推荐读物

由于我在同一条船上(OOP 背景,学习 FP),我建议您阅读一些我非常欣赏的读物:

Functional Programming for Everyday .NET Development,作者:杰里米·米勒。一篇很棒的文章(虽然格式很差),展示了 C# 上 FP 的许多技术和实际的实际示例。

Real-World Functional Programming,作者 Tomas Petricek。一本主要涉及 FP 概念的好书,试图解释它们是什么,什么时候应该使用它们。 F# 和 C# 中都有很多示例。此外,Petricek's blog 是一个很好的信息来源。

【讨论】:

不要忘记您可以将 F# 和 C# 代码混合在一起,这样您就可以充分利用它们的优点 您的回答是 .Net 强大功能的一个很好的例子。它表明它能够利用这两种范式的力量。 嘿,对不起,如果我开始了一些燃烧。我并不是说其他​​平台没有那么强大,只是 .NET 不仅支持 OOP。例如它有尾调用优化。 我不认为 FP 和 OOP 是正交的。使用函数式构造与函数式编程不同。当然,在 Linq 中使用像 lambdas 这样的函数式构造可以减少 OO,但它仍然不是函数式编程。 FP 是函数是一等公民的地方,而 OOP 是类是一流的构建块(或类似的东西 - 我确实意识到有多种 OOP)。 Imo,正确的措辞是“有多种范式语言,可让您编写 OOP 结构和 FP 结构,从而在此过程中减少 OOP 和 FP”。 @nawfal,直到您可以指出两种范式中的某些内在特征并说它们不兼容,它们是正交的:这就是讨论的核心。从定义上讲,FP 与命令式编程不兼容,但 OOP 并不局限于命令式编程。我们对这些概念使用不同的词的原因是为了让我们可以谈论它们:当你把它们混为一谈时,你只会强迫我们不必要地想出新词。【参考方案3】:

面向对象编程提供:

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

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

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

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

【讨论】:

类型类不是隐式转换为其他类型的机制。它们是为一种类型定义的一组函数的描述,以提供一种多态形式。与 Java 风格的 OOP 最接近的是接口,尽管 Haskell 类型类有一些重要的区别。【参考方案4】:

    如果您处于高度并发的环境中,那么纯函数式编程很有用。缺乏可变状态使得并发几乎是微不足道的。请参阅 Erlang。

    在多范式语言中,如果可变状态的存在必须是实现细节,您可能希望对某些事物进行功能建模,因此 FP 是问题域的一个很好的模型。例如,请参阅 Python 中的列表推导或 D 编程语言中的 std.range。这些灵感来自函数式编程。

【讨论】:

函数式编程与面向对象编程的比较

函数式编程作为结构化编程的一种,正在受到越来越多的重视。工程中不在只是面向对象编程,更多的人尝试着开始使用函数式编程来解决软件工程中遇到的问题。           什么是函数式... 查看详情

无状态面向对象编程与函数式编程?

】无状态面向对象编程与函数式编程?【英文标题】:StatelessObjectOrientedProgrammingvs.FunctionalProgramming?【发布时间】:2011-11-1606:15:09【问题描述】:如今,越来越多的注意力转向函数式编程的主要原因之一是多线程/处理的兴起,以... 查看详情

函数式编程与面向对象编程的比较

      函数式编程作为结构化编程的一种,正在受到越来越多的重视。工程中不在只是面向对象编程,更多的人尝试着开始使用函数式编程来解决软件工程中遇到的问题。        ... 查看详情

函数式编程与面向对象编程的比较

转自: http://www.cnblogs.com/zhenw/p/6160931.html 函数式编程作为结构化编程的一种,正在受到越来越多的重视。工程中不在只是面向对象编程,更多的人尝试着开始使用函数式编程来解决软件工程中遇到的问题。   &n... 查看详情

函数式编程与面向对象编程[3]:scala的oop-fp混合式编程与抽象代数理论

函数式编程与面向对象编程[3]:Scala的OOP-FP混合式编程与抽象代数理论之剑2016.5.423:55:19目录函数式编程与面向对象编程[3]:Scala的OOP-FP混合式编程与抽象代数理论 查看详情

函数式编程和面向对象编程(代码片段)

介绍函数式编程,以函数思维作为核心,在这种思维的角度去思考问题。这种编程最重要的基础就是λ演算,接受函数当作输入输出。面向对象编程,把问题看作由对象的属性与对象所进行的行为组成。基于对象的概念,以类作... 查看详情

面向对象函数式编程与并行

作者:江宏链接:https://www.zhihu.com/question/19728806/answer/18575066来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。这个问题的根本在于OOP是基于状态的。每个对象都维护着自己的状态,暴露给... 查看详情

scala学习(函数式编程面向对象编程)(代码片段)

文章目录函数式编程基础函数编程函数定义函数参数函数至简原则高阶函数编程面向对象编程基础面向对象编程高阶面向对象编程函数式编程基础函数编程函数定义packagelearn03objectdemo01defmain(args:Array[String]):Unit=//无参、无返回... 查看详情

scala学习(函数式编程面向对象编程)(代码片段)

文章目录函数式编程基础函数编程函数定义函数参数函数至简原则高阶函数编程面向对象编程基础面向对象编程高阶面向对象编程函数式编程基础函数编程函数定义packagelearn03objectdemo01defmain(args:Array[String]):Unit=//无参、无返回... 查看详情

函数与函数式编程

函数与函数式编程 纵观JavaScript中所有必须需要掌握的重点知识中,函数是我们在初学的时候最容易忽视的一个知识点。在学习的过程中,可能会有很多人、很多文章告诉你面向对象很重要,原型很重要,可是却很少有人告... 查看详情

《架构之美》阅读笔记06

...、阅读内容第五部分第十三章软件架构:面向对象与面向函数第十四章重读经典二、笔记总结(1)面向对象与面向函数函数式编程能够更好的实现模块化设计。在面向对象的编程方式出现之后,我们发现面向对象的程序设计,... 查看详情

函数式编程思维学习

1. 语言的演进   函数式编程与面向对象编程对于代码的重用方式是不同的,面向对象喜欢创建有很多操作的各种数据结构,函数式变成的数据结构却很少。  函数式编程重用表现在函数的通用性上,面向对... 查看详情

python入门自学进阶——5--类与对象

面向对象编程是函数式编程的一种变化。python既可以函数式编程,也可以面向对象编程。函数式编程可以做所有事,只是看适不适合,如果使用面向对象更简洁,就使用面向对象。对比:函数式编程,定义... 查看详情

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

第9章 从面向对象到函数式编程假如本书的写作时间倒退回十年前,书名可能会变成JavaScript面向对象编程思想。自上世纪90年代兴起的面向对象编程思想随Java的繁荣达于顶点,在JavaScript从一门只被用来编写零星的简单的... 查看详情

面向对象

面向对象前言:java,c#只支持面向对象,python即支持函数式编程,也支持面向对象编程。一,函数式编程,面向对象编程1###函数式编程2defmail(email,message):3print("去发吧!")4returnTrue56mail("[email protected]","好人")7891011###面向对象:... 查看详情

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

】混合面向对象和函数式编程【英文标题】:Mixingobject-orientedandfunctionalprogramming【发布时间】:2010-11-0404:13:18【问题描述】:有哪些语言可以同时促进面向对象和函数式编程?我知道任何支持一流函数的语言都可以被认为是函数... 查看详情

为什么说面向对象编程和函数式编程都有问题(代码片段)

我不理解为什么人们会对面向对象编程和函数式编程做无休无止的争论。就好象这类问题已经超越了人类智力极限,所以你可以几个世纪的这样讨论下去。经过这些年对编程语言的研究,我已经清楚的看到了问题的答案,所以,... 查看详情

面向对象编程

一、概述  在学习面向对象之前,我们用函数来封装我们的功能,当我们要使用时,就调用函数来实现我们的需求。现在我们学习了面向对象的知识,知道了类和对象,其实函数式编程和面向对象编程都可以减少重复代码,不... 查看详情