FP中的类型与OOP中的对象有何根本不同?

时间:2016-10-19 10:37:35

标签: functional-programming elixir

原谅我的无知,因为我是FP的新手。一直在使用Elixir,所以我给它贴了标签。

当我使用Elixir的iex时,我可以使用i检查变量的类型。例如i "hello"告诉我,我可以在其上使用String模块的功能。我可以做String.downcase "HELLO",这看起来就像向返回另一个对象的对象发送消息,但以不同的方式表达,看起来像一个数学函数。 i帮助器似乎也在检查对象的类,然后帮助我找出该对象中可用的所有方法。

我理解不变性是函数式编程的一个关键特性。我也可以使用许多OO语言轻松实现不变性,但是责任在程序员身上。

我一直在阅读Elixir书籍和博客,建议我忘记我的OO心态,并从根本上区别地思考。我只是不明白他们的根本不同,当唯一的区别是不变性时需要改变思维方式。

2 个答案:

答案 0 :(得分:1)

我认为您的问题可能更准确地指定为

  

“类和代数数据类型之间有什么区别?”

听起来你知道一个对象和一个类是什么,所以你可以通过阅读ADT来完成这个难题:

https://en.wikipedia.org/wiki/Algebraic_data_type

理解ADT和类之间差异的另一个关键是类处理数据和方法的封装,而ADT通常仅限于数据。但请注意,现代趋势是混合2,参见例如Scala的案例类。

答案 1 :(得分:1)

i helper函数不会检查对象的类",它基本上是一个对Elixir中的核心术语类型进行操作的协议。 Elixir中的每个数据值都是这些类型之一或它们的组合。

[Atom, Integer, Float, BitString, Regexp, PID, Function, Reference, Port, Tuple, List, Map]

i命令进行了一些额外的检查,以区分属于标准库的这些类型的变体,例如Structs和帮助解决erlang char_list问题。它达不到 除此之外;如果你使用复杂的组合类型,所有 它知道的是组成的最高级别。

如果您只局限于这些基础知识和标准库,那么与OO的区别并不明显。但是,当您开始编写特定于代码的数据结构时,您真正需要留下OO思想的地方。

Elixir中的子类或子类型模块没有办法[1]。没有猴子补丁;无法向String添加新函数。虽然您可以使用模块和结构来复制单个对象并编写乍一看OO的代码,但是一旦您跨越某种复杂程度,这种思维方式就会崩溃。

关于面向对象思考的警告是针对代码的更大架构。当您提出这些问题时,Elixir最简单:

我的数据结构是什么?

我需要对这些数据结构进行哪些转换?

如果你开始考虑OO方式,你会遇到麻烦。

我的名词是什么?

每个名词的动词是什么?

虽然这些问题乍一看似乎相似,但不同之处在于功能并非数据固有。您可以将任何模块中的任何函数应用于数据。这种数据和功能的分离是关键的区别。

[1] - Elixir足够灵活,如果你足够努力,你可以在其中实现某种OO系统。