由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
Programming版 - oop还是跟fp是对立的
相关主题
functional programming的两个方面一道 memset in C++的题
Scala,F#或haskell怎么用DI?return value of a python function...
请教一个python OOP 实现的问题听说有些公司用haskell代替node
func调用结束时出错感觉学习fp
How to use a function return by reference in C++PostgREST有人生产环境用过没 貌似适合猛糙快CRUD
请教个virtual function的问题haskell 真是逆天, 各种特殊符号都有特殊用途
也问个二维数组的函数传递问题这么说吧,fp不是否定变量,而是控制变量的范围
C++面试题haskell 真是逆天, 各种特殊符号都有特殊用途
相关话题的讨论汇总
话题: object话题: oop话题: fp话题: class话题: obj
进入Programming版参与讨论
1 (共1页)
z****e
发帖数: 54598
1
fp为了保证func的复用,尽量抹杀object的存在
因为class/object这种东西是特殊的数据结构
会导致func跟这种特殊的结构绑定
就很难复用,比如go(USACity la)和go(ChineseCity gz)
是不一样的,因为参数的结构不一样,这就限制了其复用
所以最后fp为了能够重用,写的func参数都是map, list,sring,int这些
而map&list注定对于一个object描述的力度是有限的
限制少木有错,但是就容易包含有各种错误等等
所以为了让func独立出去,稳定其1st class的地位
注定要削弱class/object的存在感
而oop则反过来,提倡并鼓励使用class/object
像java这种,则强迫func寄托在object下面
虽然你也可以定义全局的Util,但是毕竟static方法是很少滴
object才是1st class的地位,这样做的好处就是
不依赖func,而依赖每个object自身
每个class自己有啥问题,自己搞定,当然会有各种搞不定
搞不定没关系,异常catch住,然后收拾掉就好
不要影响其他object就行,当然这样做的结果就是
如果object无法重用,则下面的func都无法重用
所以要重用的话,必需先让object有办法重用起来
当然这么看,也可以说这两个不冲突
把fp想成是制作一堆巨大的static方法
其他的oop该怎么做还是怎么做
不过一般而言,static部分是可以托管的
spring就是其中一种托管办法,顺手抄个轮子就好了
没有必要自己去折腾,也木有时间,自己写还要维护,麻烦
所以用scala写类库,定义dsl,然后包装成jars丢出去
其他人用java就可以直接调用这些jars,是非常合理的
能解释为啥spark等用scala写
N********n
发帖数: 8363
2
W/ generic OOP is able to decouple funcs from classes already. If it's
needed it's there. OOP funcs don't have to be bound to a class.
It just has to be a real generic like that of C#, rather than type
erasure garbage JAVA does.

【在 z****e 的大作中提到】
: fp为了保证func的复用,尽量抹杀object的存在
: 因为class/object这种东西是特殊的数据结构
: 会导致func跟这种特殊的结构绑定
: 就很难复用,比如go(USACity la)和go(ChineseCity gz)
: 是不一样的,因为参数的结构不一样,这就限制了其复用
: 所以最后fp为了能够重用,写的func参数都是map, list,sring,int这些
: 而map&list注定对于一个object描述的力度是有限的
: 限制少木有错,但是就容易包含有各种错误等等
: 所以为了让func独立出去,稳定其1st class的地位
: 注定要削弱class/object的存在感

c******o
发帖数: 1277
3
everything in Scala is a Object, and Scala can be pure FP.
z****e
发帖数: 54598
4
那不行,我没有办法跟m$ couple起来
钱很重要,不能两个人分,要不然不用开源了
这个也要decoupling

【在 N********n 的大作中提到】
: W/ generic OOP is able to decouple funcs from classes already. If it's
: needed it's there. OOP funcs don't have to be bound to a class.
: It just has to be a real generic like that of C#, rather than type
: erasure garbage JAVA does.

z****e
发帖数: 54598
5
那这个object太general了
没啥用,也就做点clone,hashcode,equals这些

【在 c******o 的大作中提到】
: everything in Scala is a Object, and Scala can be pure FP.
c******o
发帖数: 1277
6
the good about OO is its encapsulation, the bad of OO is the dynamic part (
including inheritance, polymorphism etc.)
For internal state, if you want to use it in parallel/distributed env, you
will have to make it explicit to outside, or just make it immutable anyway.

【在 z****e 的大作中提到】
: 那这个object太general了
: 没啥用,也就做点clone,hashcode,equals这些

b*******g
发帖数: 603
7
Indeed for complicate concurrency system, FP is better. But concurrency is
way overrated. 99% of web apps are some sort of CRUD and no synchronization
is necessary, or contention can only happen in DB. Even for the 1%, it's
probably one or a few micro services in infrastructure that really needs it.

【在 c******o 的大作中提到】
: the good about OO is its encapsulation, the bad of OO is the dynamic part (
: including inheritance, polymorphism etc.)
: For internal state, if you want to use it in parallel/distributed env, you
: will have to make it explicit to outside, or just make it immutable anyway.

z****e
发帖数: 54598
8
就是get方法嘛
fp纯粹的异步也有问题
很多环境需要同步
哪怕是一个棋牌乐,一局也需要你同步
一般的website还是偏简单了

【在 c******o 的大作中提到】
: the good about OO is its encapsulation, the bad of OO is the dynamic part (
: including inheritance, polymorphism etc.)
: For internal state, if you want to use it in parallel/distributed env, you
: will have to make it explicit to outside, or just make it immutable anyway.

a*****e
发帖数: 1700
9
你这个理解有点片面。
首先,go(USACity la)和go(ChineseCity gz) 这种,至少在 Haskell 和 Scala 里完
全不是问题,因为有 typeclass 可以做 type-based dispatch,这叫做 ad-hoc
polymorphism。我相信你的原意是说 parametric polymorphism 和 OOP 有冲突,但这
不是 FP 和 OOP 有冲突的原因。而且 OOP 里面也可以毫无偏差地实现 parametric
polymorphism,所以针对 parametric polymorphism,FP 和 OOP 没有冲突。
FP 和 OOP 真正不同的地方在于:
在 FP 里面,type is closed,function is extensible (to handling more types).
在 OOP 里面,function is closed,type is extensible (to have more functions
)。
也就是说 OOP 是 extend objects,而 FP 是 extend functions (也即 ad-hoc
polymorphism)。其实两者并无绝对的冲突,也可以共容(见 OCaml 和 Scala),不同
的概念适用不同的场合而已。
实际使用中,反而是对 mutability 的态度上分歧比较大。但这和是否 FP 或 OOP 其
实没有关系。
另外一个比较宽泛的问题是关于谁更 modular 的争论,但是 Haskell typeclass 本身
也有这方面的问题,一直被 SML 的死忠派诟病,也就不多说了。

【在 z****e 的大作中提到】
: fp为了保证func的复用,尽量抹杀object的存在
: 因为class/object这种东西是特殊的数据结构
: 会导致func跟这种特殊的结构绑定
: 就很难复用,比如go(USACity la)和go(ChineseCity gz)
: 是不一样的,因为参数的结构不一样,这就限制了其复用
: 所以最后fp为了能够重用,写的func参数都是map, list,sring,int这些
: 而map&list注定对于一个object描述的力度是有限的
: 限制少木有错,但是就容易包含有各种错误等等
: 所以为了让func独立出去,稳定其1st class的地位
: 注定要削弱class/object的存在感

z****e
发帖数: 54598
10
dispatch显然是错误的
随着class的数量上升
你这个dispatch会拼命增加
每增加一个,你就需要回去修改源代码
把你累死,最后还不如干脆就map,list算了
说到底就是不需要修改源代码的基础之上增加class是最优的
所以fp在这一块是非常非常受限
scala本身之所以不愿意抛弃oop也是出于这个考虑
任何switch, dispatch, if else这些都属于不合适的
最理想的就是想加就加,想拆就拆,而不用改动其他部分代码

).
functions

【在 a*****e 的大作中提到】
: 你这个理解有点片面。
: 首先,go(USACity la)和go(ChineseCity gz) 这种,至少在 Haskell 和 Scala 里完
: 全不是问题,因为有 typeclass 可以做 type-based dispatch,这叫做 ad-hoc
: polymorphism。我相信你的原意是说 parametric polymorphism 和 OOP 有冲突,但这
: 不是 FP 和 OOP 有冲突的原因。而且 OOP 里面也可以毫无偏差地实现 parametric
: polymorphism,所以针对 parametric polymorphism,FP 和 OOP 没有冲突。
: FP 和 OOP 真正不同的地方在于:
: 在 FP 里面,type is closed,function is extensible (to handling more types).
: 在 OOP 里面,function is closed,type is extensible (to have more functions
: )。

相关主题
请教个virtual function的问题一道 memset in C++的题
也问个二维数组的函数传递问题return value of a python function...
C++面试题听说有些公司用haskell代替node
进入Programming版参与讨论
z****e
发帖数: 54598
11
polymorphism只是一个折中的方案
在任何时候polymorphism都会随着规模的增加而线性增加
最后当项目大了之后,polymorphism这部分代码会变得很大很粗
不管是oop还是fp,都应该想办法避免polymorphism
所以你说可以做到polymorphism,没啥,应该想办法避开polymorphism
我觉得那次谁说的
oop和fp的区别仅仅是在于看你的封装是在object级别还是func级别
那句话是至理名言,oop和fp还是有冲突的部分的
因为object和func只要存在,就会互相影响

).
functions

【在 a*****e 的大作中提到】
: 你这个理解有点片面。
: 首先,go(USACity la)和go(ChineseCity gz) 这种,至少在 Haskell 和 Scala 里完
: 全不是问题,因为有 typeclass 可以做 type-based dispatch,这叫做 ad-hoc
: polymorphism。我相信你的原意是说 parametric polymorphism 和 OOP 有冲突,但这
: 不是 FP 和 OOP 有冲突的原因。而且 OOP 里面也可以毫无偏差地实现 parametric
: polymorphism,所以针对 parametric polymorphism,FP 和 OOP 没有冲突。
: FP 和 OOP 真正不同的地方在于:
: 在 FP 里面,type is closed,function is extensible (to handling more types).
: 在 OOP 里面,function is closed,type is extensible (to have more functions
: )。

a*****e
发帖数: 1700
12
你没搞明白 haskell typeclass 的语义和实现,这不怪你。增加新 typeclass
instance 不需要回去改代码,和 OO 里面的 class/object 的 method dispatch 实现
区别不大。

【在 z****e 的大作中提到】
: dispatch显然是错误的
: 随着class的数量上升
: 你这个dispatch会拼命增加
: 每增加一个,你就需要回去修改源代码
: 把你累死,最后还不如干脆就map,list算了
: 说到底就是不需要修改源代码的基础之上增加class是最优的
: 所以fp在这一块是非常非常受限
: scala本身之所以不愿意抛弃oop也是出于这个考虑
: 任何switch, dispatch, if else这些都属于不合适的
: 最理想的就是想加就加,想拆就拆,而不用改动其他部分代码

z****e
发帖数: 54598
13
那你给个例子看看
给zkss?

【在 a*****e 的大作中提到】
: 你没搞明白 haskell typeclass 的语义和实现,这不怪你。增加新 typeclass
: instance 不需要回去改代码,和 OO 里面的 class/object 的 method dispatch 实现
: 区别不大。

z****e
发帖数: 54598
14
你想说的是parametric polymorphism吧
也就是通过不同类型的class塞入方法参数,从而调用不同的方法吧?
这个还是需要通过源代码来修改
无论你怎么写,这个go方法你还是需要增加一部分新代码来配合你新增的那个class
随着class的增加,你的这个go方法会越发地膨胀
所以最后你会发现,还不如干脆全部map和list掉算了
为什么fp经常被用来做数据处理呢?
因为数据处理的class很少,几乎都是数字,不需要怎么描述性质的东西
比较容易搞,你要是不信,我们具体例子具体分析
从例子来说

【在 a*****e 的大作中提到】
: 你没搞明白 haskell typeclass 的语义和实现,这不怪你。增加新 typeclass
: instance 不需要回去改代码,和 OO 里面的 class/object 的 method dispatch 实现
: 区别不大。

a*****e
发帖数: 1700
15
纠正一下你的概念,parametric polymorphism 是指将 type 作为参数,通常理解为
forall 就可以了。
type class 是 ad-hoc polymorphism,是在 parametric 的基础上加上类型类(
typeclass)的限制,简单理解可以是把 typeclass 当作是 java class,类型的
instance 定义当作是 java sub-class 定义。都说了,和 java class 实现差别不大
,如果你认为差别很大,请举个具体例子。

【在 z****e 的大作中提到】
: 你想说的是parametric polymorphism吧
: 也就是通过不同类型的class塞入方法参数,从而调用不同的方法吧?
: 这个还是需要通过源代码来修改
: 无论你怎么写,这个go方法你还是需要增加一部分新代码来配合你新增的那个class
: 随着class的增加,你的这个go方法会越发地膨胀
: 所以最后你会发现,还不如干脆全部map和list掉算了
: 为什么fp经常被用来做数据处理呢?
: 因为数据处理的class很少,几乎都是数字,不需要怎么描述性质的东西
: 比较容易搞,你要是不信,我们具体例子具体分析
: 从例子来说

z****e
发帖数: 54598
16
最简单例子,就不说场景
func1(Object1 obj1)
func2(Object2 obj2)
你觉得这两个是不是func1&obj1, func2&obj2两个紧密耦合了起来?
对比
obj1.func1
obj2.func2
其实是一回事
因为任何改动obj1的地方都会牵涉func1的改动
对吧?
对比
func1(Map map1)
func2(Map map2)
是不是就要更为松散呢?
这个时候你叠加func1&func2就很容易
当然一般这么理想是比较难做到的
多数时候还是这样
func1(Object obj)
func2(Object obj)
因为obj不变,所以func1(func2(obj))的叠加就很容易
但是如果obj在func1&func2中是不一样的
就变成紧耦合了,func和obj无法分离
所以fp不适合做这种一堆对象的场景,如果都是information
也就是map&list,就很容易了
沙发就在说这个,你回的一大通,我还以为你知道我在说啥呢

【在 a*****e 的大作中提到】
: 纠正一下你的概念,parametric polymorphism 是指将 type 作为参数,通常理解为
: forall 就可以了。
: type class 是 ad-hoc polymorphism,是在 parametric 的基础上加上类型类(
: typeclass)的限制,简单理解可以是把 typeclass 当作是 java class,类型的
: instance 定义当作是 java sub-class 定义。都说了,和 java class 实现差别不大
: ,如果你认为差别很大,请举个具体例子。

a*****e
发帖数: 1700
17
我觉得你要说的是:
func1(Object obj)
func2(Object obj)
这种写法,你在 func1 和 func2 的 body 里面只知道对象是 Object,从而不能谈论
更多。
换成 OO 的方式, obj->func1() obj->func2(),只需要知道 Object class 里面有
func1 和 func2 两个成员函数,而不需要知道 obj 具体是 Object class 还是它的
sub class。通过 sub class 来 overload method 可以实现更多功能。
这是你的意思,对不对?
这种 OO 里面的做法换成用 Haskell:
class ObjectClass a where
func1 :: a -> ...
func2 :: a -> ...
type ObjectType1 = ...
type ObjectType2 = ...
instance ObjectClass ObjectType1 where
func1 = ...
func2 = ...
instance ObjectClass ObjectType2 where
func1 = ...
func2 = ...
obj1 :: ObjectType1
obj1 = ...
obj2 :: ObjectType1
obj2 = ...
main = ... func1(obj1) ... func2(obj2) ..
没有任何问题,和你上面 OO 的做法几乎是一样的,这里定义 ObjectType1 和
ObjectType2 的关于 ObjectClass 的 instance,就对应了 java 里面的 sub class。
Haskell typeclass 比 java class 要灵活多了,可以定义 ObjectType1 属于
ObjectClass 也可以定义 ObjectType1 属于 OtherClass,这类似 multi inheritance
。还可以定义 multi parameter type class,用多个 type 组合起来定义一个
instance,可以用来表达多个 type 之间的规则。

【在 z****e 的大作中提到】
: 最简单例子,就不说场景
: func1(Object1 obj1)
: func2(Object2 obj2)
: 你觉得这两个是不是func1&obj1, func2&obj2两个紧密耦合了起来?
: 对比
: obj1.func1
: obj2.func2
: 其实是一回事
: 因为任何改动obj1的地方都会牵涉func1的改动
: 对吧?

z****e
发帖数: 54598
18
不是
我的意思是在这个时候,fp应该能够体现出比oop更为高效的地方才对
比如
func1(MyObject obj)
func2(MyObject obj)
func3(MyObject obj)
func4(MyObject obj)
func5(MyObject obj)
func6(MyObject obj)
...
这个时候,因为MyObject结构都是一样的
所以就很容易叠加各种函数
以及对函数做归类,整理,都很容易
但是如果这个时候MyObject的结构改变了
那你就得对这一通函数一顿改
麻烦死你,而且最痛苦的是
这些func可能放在不同的地方,那找起来就麻烦了
所以要控制数据结构数量
最好都是map&list,这样基本上没啥好改的
如果是oop
那是这样
MyObj1.func1
MyObj1.func2
MyObj2.func2
MyObj3.func3
...
本身func不是1st class,所以从属于object
而改动其中一个obj,不会影响到其他obj,所以加减obj就很容易
也很自然,你要改其中任何一个obj的结构也相对容易
尤其是如果这个obj的方法只负责处理自身属性的时候
那改动其中一个结构,几乎不会有太大的改动
是很容易的一件事
func和obj是多对多关联
看你用哪个作为标准整理了

【在 a*****e 的大作中提到】
: 我觉得你要说的是:
: func1(Object obj)
: func2(Object obj)
: 这种写法,你在 func1 和 func2 的 body 里面只知道对象是 Object,从而不能谈论
: 更多。
: 换成 OO 的方式, obj->func1() obj->func2(),只需要知道 Object class 里面有
: func1 和 func2 两个成员函数,而不需要知道 obj 具体是 Object class 还是它的
: sub class。通过 sub class 来 overload method 可以实现更多功能。
: 这是你的意思,对不对?
: 这种 OO 里面的做法换成用 Haskell:

T*******x
发帖数: 8565
19
这个有道理。

【在 z****e 的大作中提到】
: fp为了保证func的复用,尽量抹杀object的存在
: 因为class/object这种东西是特殊的数据结构
: 会导致func跟这种特殊的结构绑定
: 就很难复用,比如go(USACity la)和go(ChineseCity gz)
: 是不一样的,因为参数的结构不一样,这就限制了其复用
: 所以最后fp为了能够重用,写的func参数都是map, list,sring,int这些
: 而map&list注定对于一个object描述的力度是有限的
: 限制少木有错,但是就容易包含有各种错误等等
: 所以为了让func独立出去,稳定其1st class的地位
: 注定要削弱class/object的存在感

1 (共1页)
进入Programming版参与讨论
相关主题
haskell 真是逆天, 各种特殊符号都有特殊用途How to use a function return by reference in C++
我来挖坑, 谈谈OOP/FP/SQL和人类思维习惯请教个virtual function的问题
关于变量也问个二维数组的函数传递问题
C++ questionsC++面试题
functional programming的两个方面一道 memset in C++的题
Scala,F#或haskell怎么用DI?return value of a python function...
请教一个python OOP 实现的问题听说有些公司用haskell代替node
func调用结束时出错感觉学习fp
相关话题的讨论汇总
话题: object话题: oop话题: fp话题: class话题: obj