let*_*nje 74 oop paradigms programming-languages functional-programming scala
我一次又一次地听到,我正在努力理解并验证FP和OO是正交的想法.
首先,2个概念的正交意味着什么?
FP尽可能地鼓励不变性和纯度,而OO似乎是为状态和变异而构建的 - 一个有点组织的命令式编程版本?我意识到对象可以是不可变的,但OO似乎意味着状态/改变我.
它们看起来像是对立的.这对他们的正交性有何影响?
像Scala这样的语言可以很容易地执行OO和FP,这是否会影响这两种方法的正交性?
Mar*_*ers 70
正交性意味着两件事是无关的.它来自数学,它意味着垂直.在通常使用中,它可能意味着两个决策无关,或者一个主题在考虑另一个主题时无关紧要.如这里所使用的,正交意味着一个概念不暗示或排除另一个概念.
面向对象编程和函数编程这两个概念并不相互矛盾.面向对象并不意味着可变性.许多以传统方式介绍面向对象程序的人通常首先使用C++,Java,C#或类似语言,其中可变性很常见甚至鼓励(标准库提供了多种可变类供人们使用).因此,很多人将面向对象的编程与命令式编程和可变性相关联是可以理解的,因为这是他们学习它的方式.
然而面向对象的编程涵盖了以下主题
这些都不意味着可变性,并且它们都不包括函数式编程.所以是的,他们是正交的,因为他们是不同的概念.它们不是对立的 - 你可以使用一个,或另一个,或两者(甚至两者都不).像Scala和F#这样的语言尝试将两种范例组合成一种语言:
Scala是一种多范式编程语言,旨在集成面向对象编程和函数编程的功能.
F#是一种简洁,富有表现力且高效的.NET 功能和面向对象语言,可帮助您编写简单的代码来解决复杂问题.
mis*_*tor 15
首先,2个概念的正交意味着什么?
这意味着这两个概念没有对比的想法或彼此不相容.
FP尽可能地鼓励不变性和纯度.和OO似乎是为状态和变异而构建的东西(一种有点组织的命令式编程版本?).我确实意识到对象可以是不可变的.但OO似乎意味着状态/改变我.
它们看起来像是对立的.它如何影响它们的正交性?
像Scala这样的语言可以很容易地完成OO和FP,这是否会影响2种方法的正交性?
OO是关于封装,对象组成,数据抽象,通过子类型的多态性,以及必要时的受控变异(在OO中也鼓励不变性).FP是关于函数组合,控制抽象和约束多态(也称为参数多态).因此,这两个想法并不矛盾.它们都为您提供了不同类型的权力和抽象机制,这些机制当然可以用一种语言.实际上,这是Scala构建的论文!
在他在谷歌的Scala实验演讲中,Martin Odersky非常清楚地解释了他如何相信两个概念--OO和FP - 彼此正交以及Scala如何优雅地无缝地将这两个范例统一到Scala社区中广为人知的新范例中对象功能范式.一定要看你说话.:-)
sep*_*p2k 12
首先,2个概念的正交意味着什么?
这意味着它们不会相互影响.即功能语言的功能性也不低,因为它也是面向对象的.
它们看起来像是对立的.它如何影响它们的正交性?
如果它们是对立的(即纯函数式语言不可能是面向对象的),它们根据定义将不是正交的.但是我不相信这是这种情况.
和OO似乎是为状态和变异而构建的东西(一种有点组织的命令式编程版本?).我确实意识到对象可以是不可变的.但OO似乎意味着状态/改变我.
虽然大多数主流OO语言都是如此,但OO语言没有理由需要具有可变状态.
如果一种语言具有对象,方法,虚拟继承和ad-hoc多态,那么它就是一种面向对象的语言 - 它是否也具有可变状态.
对于两个正交的概念意味着它们可以在任何给定的表现中独立地实现到任何程度.例如,考虑到音乐,您可以对音乐作品进行分类,了解它是如何调和的,以及它的节奏程度."和声"和"节奏"这两个概念在正调和节奏片,不和谐和心律片,以及不和谐和节奏片以及谐音和心律失常片的意义上是正交的.
应用于原始问题,这意味着有纯粹的功能性,非面向对象的编程语言,如Haskell,纯粹面向对象,"非功能"语言,如Eiffel,还有既不是C语言也不是C语言的语言.如Scala.
简单来说,Scala是面向对象意味着您可以定义数据结构("类"和"特征"),这些数据结构使用操纵此数据的方法封装数据,从而保证这些结构("对象")的实例始终位于已定义的状态(对象在其类中列出的合同).
另一方面,Scala是一种函数式语言意味着它支持不可变的可变状态,并且函数是第一类对象,它可以像任何其他对象一样用作局部变量,字段或其他函数的参数.除此之外,Scala中的几乎每个语句都有一个值,它鼓励您使用函数式编程风格.
Scala中面向对象编程和函数编程的正交性意味着您作为程序员可以自由选择适合您目的的这两个概念的任何混合.您可以使用纯粹的命令式样式编写程序,仅使用可变对象而不使用函数作为对象,另一方面,您也可以在Scala中编写纯函数程序而不使用任何面向对象的功能.
Scala真的不要求你使用一种风格或另一种风格.它可以让您选择两全其美的方案来解决您的问题.
与所有分类一样,将编程语言划分为功能,面向对象,程序等等是虚构的.但我们确实需要分类,而在编程语言中,我们通过一组语言特征和使用该语言的人的哲学方法进行分类(后者受前者影响).
因此,有时"面向对象"的语言可以成功地采用"功能"编程语言的特性和哲学,反之亦然.但肯定不是所有的编程语言特性和哲学都是兼容的.
例如,像OCaml这样的函数语言通过词法作用域和闭包来完成封装,而面向对象的语言使用公共/私有访问修饰符.这些本身并不是不兼容的机制,但它们是多余的,而像F#这样的语言(一种主要用于与明确的面向对象的.NET库和语言堆栈协调一致的功能性语言)必须深入研究差距.
作为另一个例子,OCaml使用结构类型系统进行面向对象,而大多数面向对象的语言使用标称类型系统.这些非常不兼容,并且有趣地表示面向对象语言领域内的不兼容性.
您可以将函数作为对象和对象实现为函数集合,因此这两个概念之间显然存在某种关系.
FP尽可能地鼓励不变性和纯度
你在谈论纯函数式编程.
而OO似乎是建立在状态和变异之上的
不要求对象是可变的.我会说对象和变异是正交概念.例如,OCaml编程语言为纯功能对象更新提供了语法.
像Scala这样的语言可以很容易地完成OO和FP
并不是的.缺少尾调用优化意味着大多数惯用的纯函数代码将在Scala中堆栈溢出,因为它会泄漏堆栈帧.例如,继续传递风格(CPS)和文章中描述的所有技术,由布鲁斯麦克亚当包裹起来.没有简单的方法可以解决这个问题,因为JVM本身无法进行尾调用优化.
关于纯函数式编程和面向对象编程的正交性,我会说它们至少接近于正交,因为纯函数式编程只处理小型程序(例如高阶函数),而面向对象编程处理大型函数程序的规模结构.这就是函数式编程语言通常为大规模结构提供一些其他机制的原因,例如标准ML和OCaml的高阶模块系统,或Common Lisp的CLOS或Haskell的类型.