OOP与功能编程(方案)的区别

waj*_*jed 5 oop scheme functional-programming

我正在观看斯坦福大学的视频课程/讲座.该课程是"计算机程序的结构和解释"

在第一次OOP讲座中,讲师(Brian Harvey)将OOP方法描述为对同一问题给出不同答案的方法,而函数式编程中的函数为某个输入提供了一定的输出.

以下代码是OOP中一个方法的示例,每次调用时都会给出不同的答案: -

(define-class (counter)
  instance-vars (count 0))
  (method (next)
    (set! count (+ count 1))
    count) )
Run Code Online (Sandbox Code Playgroud)

虽然课程以方案说明,但我并没有太注意语言本身,所以我无法解释代码; 但是"下一个"功能不能和"下一个"功能相同吗?在C中,我会声明一个全局变量,每次调用next时都会增加一个.我知道C是程序性的,但我猜测在Scheme中可以做类似的事情.

C. *_*ann 8

好.尽管对讲师充满敬意,但这些都是对"OOP"和"函数式编程"的略微愚蠢的定义.这两个术语在工业和学术背景下都被一致地使用,不一致,更不用说非正式用途了.如果你深入挖掘一下,真正发生的是有几个正交概念 - 不同的轴,可以选择如何接近程序 - 正在混合,一组选择被任意称为" OOP"尽管没有别的东西将他们捆绑在一起.

这里涉及的两个最大的区别可能是:

  • 身份与价值:您是否通过隐式身份(基于记忆位置或诸如此类)对事物进行建模并允许它们任意改变?或者你是否按照自己的价值来塑造事物,没有固有的身份概念?如果你说x = 4这意味着这x是4号永恒的柏拉图式理想的别名,或者是x目前是4的东西的名称,但可能是其他东西(虽然仍然存在x)?

  • 数据与行为:您是否使用可以检查,操作和转换其表示的简单数据结构?或者您是否使用抽象行为做事情,仅根据您可以用它做的事情来表示数据,并让这些行为抽象相互运作?

大多数标准命令式语言倾向于使用身份和数据 - 指向C struct的指针尽可能纯粹是这种方法.OOP语言往往主要通过选择行为而不是数据来定义,通常也倾向于身份但不一致(参见"不可变"对象的流行度).

函数式编程通常倾向于更多地依赖于值而不是身份,同时将数据和行为混合到不同程度.

这里还有很多事情要发生,但我认为这是你在这里想到的关键部分.


如果有人好奇我之前已经详细阐述了一些:分析许多OOP语言的一些基本概念,更多关于身份/价值问题以及正式和非正式方法,看一下函数式编程中的数据/行为区别,可能是其他我无法想到的.警告,我有点啰嗦,这些都不适合胆小的人.:P


pet*_*hil 8

优秀的Haskell wiki上有一个页面,其中功能编程和OOP的差异进行了对比.除了帮助使用Haskell语言之外,Haskell wiki还是关于函数式编程的一切资源.

功能编程和OOP差异

纯函数式编程和面向对象编程之间的重要区别是:

面向对象:

数据:

  • OOP询问我该怎么处理数据?
  • 制片人:班级
  • 消费者:类方法

州:

  • OOP中的方法和对象具有一些内部状态(方法变量和对象属性),并且它们可能具有影响计算机外围设备状态,全局范围或对象或方法状态的副作用.变量赋值是具有状态的一个好兆头.

功能:

数据:

  • 函数式编程询问数据是如何构造的?
  • 生产者:类型构造函数
  • 消费者:功能

州:

  • 如果纯函数式编程曾分配给变量,则必须考虑该变量并将其作为不可变处理.纯函数式编程中一定不存在状态.
  • 具有副作用的代码通常与主要的纯函数代码体分开
  • 状态可以作为函数的参数传递,这称为延续.

OOP生成器的功能替代品

使用纯函数编程执行类似于OOP样式生成器(具有内部状态)的方法是从不同的角度处理问题,根据用例使用这些解决方案之一:

1.按顺序处理部分或全部值:

序列的类型可以是列表,数组,序列或向量.

  • Lisp car和Haskell一起first从列表中获取第一项.

  • Haskell也有take,它采用前n项,并且支持惰性求值,因此支持无限或循环序列 - 就像OOP生成器一样.

  • 两者都有first,以及不同的map,reducefold用于与功能的处理顺序的功能.

  • 矩阵通常也有一些方法mapapply每个项目的功能.

2.需要函数中的某些值:

指数可能来自离散或连续的比例(整数或浮点数).

  • 创建一个纯函数来生成索引(事件)并将它们提供给另一个纯函数(行为).这称为功能反应式编程.这是Dataflow编程的一种形式以及面向单元的编程.该Actor模型在操作上也非常有趣的选择与处理的并发线程有些相似,和!

3.使用封闭物从外部限制和封装状态

  • 这是最接近OOP方式的生成器(我认为它实际上起源于模仿闭包),并且距离纯函数式编程最远,因为闭包具有状态.