Redian新闻
>
请大家批判一下 What is Functional Programming?
avatar
s*w
3
"JavaScript has first class functions, which allows us to treat functions as
data — assign them to variables, pass them to other functions,
return them from functions, etc…"
This is totally bullshit, seems so called "functions" in Javascript are just
class objects.
avatar
n*p
4
First class里的此class非彼class

as
functions,
just

【在 s*****w 的大作中提到】
: "JavaScript has first class functions, which allows us to treat functions as
: data — assign them to variables, pass them to other functions,
: return them from functions, etc…"
: This is totally bullshit, seems so called "functions" in Javascript are just
: class objects.

avatar
r*z
5
如果没有内部的状态,没有副作用,你何必在乎是如何实现的呢?

as
functions,
just

【在 s*****w 的大作中提到】
: "JavaScript has first class functions, which allows us to treat functions as
: data — assign them to variables, pass them to other functions,
: return them from functions, etc…"
: This is totally bullshit, seems so called "functions" in Javascript are just
: class objects.

avatar
s*w
6
我知道那句话是说functions是一等公民,但它的function不就是简化过的class吗?

【在 n***p 的大作中提到】
: First class里的此class非彼class
:
: as
: functions,
: just

avatar
s*w
7
我是从OOP过来的,读着js不舒服, 觉得很乱

【在 r*****z 的大作中提到】
: 如果没有内部的状态,没有副作用,你何必在乎是如何实现的呢?
:
: as
: functions,
: just

avatar
n*p
8
why thinking function is 简化过的class? It's the other way around, class is
data and functions combo, which is unnecessary and usually class data are
mutable, they are the root cause for many concurrent programming issues.

lisp keeps data and functions seperated, and it is easier for purer FP
languages like clojure to deal with concurrent programming.
javascript or other oop+fp hybrid languages are not the best language to
learn FP.

【在 s*****w 的大作中提到】
: 我知道那句话是说functions是一等公民,但它的function不就是简化过的class吗?
avatar
s*w
9
data and functions combo, 这又有啥问题?
如果是数学公式,我完全支持FP。
但这世界是由object构成的,家里前门是红色的,这个红色就是data,就跟这扇门联系
在一起,有啥问题?

is

【在 n***p 的大作中提到】
: why thinking function is 简化过的class? It's the other way around, class is
: data and functions combo, which is unnecessary and usually class data are
: mutable, they are the root cause for many concurrent programming issues.
:
: lisp keeps data and functions seperated, and it is easier for purer FP
: languages like clojure to deal with concurrent programming.
: javascript or other oop+fp hybrid languages are not the best language to
: learn FP.

avatar
d*a
10
如果不是搞学术研究,只是为了找工作,我建议不要想得这么深邃。这是学术界可以吵
上一百年的话题。
在工业界,需要(或被指定)用什么语言就用什么语言,选择的余地很小。不管是哪种
语言,尽可能学好就是了。
不过,为了求知,多讨论一下也没有坏处。记得这种问题很难有结论就行了。

【在 s*****w 的大作中提到】
: data and functions combo, 这又有啥问题?
: 如果是数学公式,我完全支持FP。
: 但这世界是由object构成的,家里前门是红色的,这个红色就是data,就跟这扇门联系
: 在一起,有啥问题?
:
: is

avatar
s*i
11
世界是由object构成的,没错。这些objects的总和称为state。
但是但是世界是变换的,不停的从state1,state2,state3的过程。
FP认为,世界的本质是这些变换函数。而state只不过是输入输出罢了。
OOP认为,世界的本质是这些state。

【在 s*****w 的大作中提到】
: data and functions combo, 这又有啥问题?
: 如果是数学公式,我完全支持FP。
: 但这世界是由object构成的,家里前门是红色的,这个红色就是data,就跟这扇门联系
: 在一起,有啥问题?
:
: is

avatar
s*w
12
一直是做oop, 这次这个工作非常不顺,有个重要原因是这个组坚持FP.

【在 d***a 的大作中提到】
: 如果不是搞学术研究,只是为了找工作,我建议不要想得这么深邃。这是学术界可以吵
: 上一百年的话题。
: 在工业界,需要(或被指定)用什么语言就用什么语言,选择的余地很小。不管是哪种
: 语言,尽可能学好就是了。
: 不过,为了求知,多讨论一下也没有坏处。记得这种问题很难有结论就行了。

avatar
d*a
13
如果要反对,不宜从哲学层次来否定FP,因为有一些项目,已经被证明了用FP来做是非
常合适的。
最好说一些具体的原因,为什么FP不适合当前的项目。这要求对FP有一定的了解。

【在 s*****w 的大作中提到】
: 一直是做oop, 这次这个工作非常不顺,有个重要原因是这个组坚持FP.
avatar
c*v
15
你这个就是共时幻觉啊。oo课本举的那些例子都是为了卖书的。door是个符号,哪里有
什么颜色呢?
程序走到这一句,你那个red什么状态是你假设出来的,你其实压根不知道的。
oo书用这些例子糊弄初学者,我认为是很不好的。复杂性被掩盖,造成乐观情绪。
用乐观情绪来洗脑。
之前我写过一个贴。德里达分析过文学理论里有这个东西。
例如古典小说里,例如悲惨世界吧,作者说一个事,然后又说一个事,说第二个事的时
候,
文本作为符号不在第一件事了。
你作为读者,还是假设第一件事同时在发生。然而真相确实是如此吗?
函数式就好比第一人称小说一样,是比较难写的。因为小说主人公的视线是被遮挡的。
不是第三人称上帝视角。
表面上看,door.color = 'red'
很自然。其实有很多问题要解决。
每个人都会遇到很多
door.color = doorcolor
这时候牛逼人物就会出来用design pattern什么解决问题.
然而那往往是在代码确定后refactor的情况下这样干比较好。
如果是糙快猛,那就抓住什么用什么吧。按照信号被处理的顺序走,或者按照一个假设
的共时存在的对象
也都可以。
函数式有一个好处。就是各种语言的函数都大同小异。我按自己定义的一些写法,写出
来的python转c
难度不大。如果你用oo,各语言的oo差别非常大的。所以我认为多语言编程的上升趋势
,也是造成
纯函数上升的一个原因。

【在 s*****w 的大作中提到】
: data and functions combo, 这又有啥问题?
: 如果是数学公式,我完全支持FP。
: 但这世界是由object构成的,家里前门是红色的,这个红色就是data,就跟这扇门联系
: 在一起,有啥问题?
:
: is

avatar
h*c
16
厉害了,老中医

【在 c*******v 的大作中提到】
: 你这个就是共时幻觉啊。oo课本举的那些例子都是为了卖书的。door是个符号,哪里有
: 什么颜色呢?
: 程序走到这一句,你那个red什么状态是你假设出来的,你其实压根不知道的。
: oo书用这些例子糊弄初学者,我认为是很不好的。复杂性被掩盖,造成乐观情绪。
: 用乐观情绪来洗脑。
: 之前我写过一个贴。德里达分析过文学理论里有这个东西。
: 例如古典小说里,例如悲惨世界吧,作者说一个事,然后又说一个事,说第二个事的时
: 候,
: 文本作为符号不在第一件事了。
: 你作为读者,还是假设第一件事同时在发生。然而真相确实是如此吗?

avatar
s*w
18
请这里支持Functional Programming的大牛们讲讲例子,教育一下大家。

【在 b***i 的大作中提到】
: 看了半天,没看到要解决什么问题。举个例子好了,
: 我要做一个3D射击游戏,用函数式编程,好在哪里?

avatar
s*w
20
oop是符合数学符合人的思维模式的。
数学最重要的一点是归纳共性,以此推演出去,比如从2两维三维到四维,比如从一般
函数到泛函分析。
oop也是归纳objects的共性,把这些放在base class里,建立一个common interface。

【在 c*******v 的大作中提到】
: 你这个就是共时幻觉啊。oo课本举的那些例子都是为了卖书的。door是个符号,哪里有
: 什么颜色呢?
: 程序走到这一句,你那个red什么状态是你假设出来的,你其实压根不知道的。
: oo书用这些例子糊弄初学者,我认为是很不好的。复杂性被掩盖,造成乐观情绪。
: 用乐观情绪来洗脑。
: 之前我写过一个贴。德里达分析过文学理论里有这个东西。
: 例如古典小说里,例如悲惨世界吧,作者说一个事,然后又说一个事,说第二个事的时
: 候,
: 文本作为符号不在第一件事了。
: 你作为读者,还是假设第一件事同时在发生。然而真相确实是如此吗?

avatar
N*r
21

map reduce 就是函数式编程最简单且最好的例子
简单的说,就是用函数处理函数

【在 s*****w 的大作中提到】
: 请这里支持Functional Programming的大牛们讲讲例子,教育一下大家。
avatar
N*r
22
另外我不明白为什么要把oop 和 fp放在一起讲
根本不是一个level的东西
oop本质上目前还是过程式语言,但不代表函数式编程里就不能有OOP, 实际上用
scheme就能模拟出一套oop的系统, 这是SICP里讲过的基础知识
avatar
n*p
23
yes, red is data, and it is not a function,
you are mixing up oop with object. They are not the same.
oop is about encapsulation, inheritance, and polymorphism, which all these
so called great features are useless(see my last post) for FP, the pure FP
language can do all OOP design patterns so easily and naturally.

【在 s*****w 的大作中提到】
: data and functions combo, 这又有啥问题?
: 如果是数学公式,我完全支持FP。
: 但这世界是由object构成的,家里前门是红色的,这个红色就是data,就跟这扇门联系
: 在一起,有啥问题?
:
: is

avatar
f*t
24
这篇文章只是试图用例子证明FP比DP简洁,但并没有任何实际意义,不就少写几行代码
么。
我只想知道有没有著名的FP工程(比如用Scala写的Kafka和Spark),正好有用OOP写的
替代品,两者比一下性能、维护难度和开发难度,就很容易看出FP吹的到底是货真价实
还是宗教信仰。

【在 n***p 的大作中提到】
: http://www.mitbbs.org/article_t/Programming/31504537.html
: http://mishadoff.com/blog/clojure-design-patterns/
: all oop "tricks" are so obvious for FP programmers.

avatar
g*t
25
数学也有很多种。代数,几何,分析 这三种基本的内容。你说的是哪种。不同的数学
分支之间的差别是极其巨大的。


: oop是符合数学符合人的思维模式的。

: 数学最重要的一点是归纳共性,以此推演出去,比如从2两维三维到四维,比如
从一般

: 函数到泛函分析。

: oop也是归纳objects的共性,把这些放在base class里,建立一个common
interface。



【在 s*****w 的大作中提到】
: oop是符合数学符合人的思维模式的。
: 数学最重要的一点是归纳共性,以此推演出去,比如从2两维三维到四维,比如从一般
: 函数到泛函分析。
: oop也是归纳objects的共性,把这些放在base class里,建立一个common interface。

avatar
g*t
26
Simulink连几条线,控制个电机速度什么的。那就是信号被几个复合函数处理。就是函
数式的。input signal,output signal是单独的控件。没有内存,状态等东西。
但是你要写个GUI,页面上几十个地方可以输入输出。那oo更方便些。


: 请这里支持Functional Programming的大牛们讲讲例子,教育一下大家。



【在 s*****w 的大作中提到】
: oop是符合数学符合人的思维模式的。
: 数学最重要的一点是归纳共性,以此推演出去,比如从2两维三维到四维,比如从一般
: 函数到泛函分析。
: oop也是归纳objects的共性,把这些放在base class里,建立一个common interface。

avatar
h*i
27
其实3D编程就是标准的函数式编程的体系结构:整个3D世界是一个scenegraph,其实就
是一个数据结构,3D engine用这个作为输入来渲染世界,渲染完了然后接受一些事件
输入(主要是用户操作和网络包)来改变这个scengraph, 在下一个时间点,渲染这个
新的scenegraph。在原则上,每次渲染都是世界完全重画。这儿3D engine是一个函数
,把代表世界的数据变成GPU能用来渲染的数据;外部事件的handler,也是些函数,把
旧世界数据变成新世界数据。我老博士论文是做的3D的东东,对这一套很熟,所以对后
来接受FP思维可能有帮助。
现在最火的React Web编程,其实就是学的3D编程原理,也就是函数式编程的原理。所
以React也学Clojurescript,搞immutable data。
因为这种编程模式,为了性能,不能真的在每个时间点都完全渲染整个世界,只能重新
渲染改过的地方,这就需要diff新旧世界。而immutable数据,diff新旧数据比mutable
数据快:因为只需要比reference,比如我们发现新旧两个nodes的references一样,如
果数据是immutable的,我们就知道以这个node为根的树没有变化,不用深挖遍历下去
了,而在mutable数据的情况下,我们不能做这样的推论,必须完全遍历比较两个树才
知道哪儿有变化。

【在 b***i 的大作中提到】
: 看了半天,没看到要解决什么问题。举个例子好了,
: 我要做一个3D射击游戏,用函数式编程,好在哪里?

avatar
h*i
28
如果你说的OOP的着眼点只是建立一个common interface,也就是所谓的多态,
polymophism,这个FP也做,而且作得更灵活直观,也不需要使用繁复的各种design
pattern来实现。比如Clojure,就有defprotocol, deftype,defrecord这些类似机制
来定义common interface。这些机制其实都是dispatch by type。 FP还有其他的机制
,比如multimethod, 可以dispatch by anything。 在Common Lisp里面,还有其他更
多的机制,比如mixins, traits之类,不少都被Scala学去了,个人觉得太复杂了,没
必要。
OOP的其他两个所谓的特征,一个是继承,这个在OOP中都已经不太鼓励了,就不提也罢
;另一个是封装,这个其实是为了对付mutable数据的问题而不得不弄出来的一个枷锁
。如果数据是immutable的,这个枷锁是完全可以被去掉,这让数据得到解放,编程更
容易。
总之,OOP的三个特征,两个是不必要的,剩下一个也限制很多,所以,基本上算是一
无是处。

【在 s*****w 的大作中提到】
: oop是符合数学符合人的思维模式的。
: 数学最重要的一点是归纳共性,以此推演出去,比如从2两维三维到四维,比如从一般
: 函数到泛函分析。
: oop也是归纳objects的共性,把这些放在base class里,建立一个common interface。

avatar
j*v
29
这个总结得不错

【在 h*i 的大作中提到】
: 如果你说的OOP的着眼点只是建立一个common interface,也就是所谓的多态,
: polymophism,这个FP也做,而且作得更灵活直观,也不需要使用繁复的各种design
: pattern来实现。比如Clojure,就有defprotocol, deftype,defrecord这些类似机制
: 来定义common interface。这些机制其实都是dispatch by type。 FP还有其他的机制
: ,比如multimethod, 可以dispatch by anything。 在Common Lisp里面,还有其他更
: 多的机制,比如mixins, traits之类,不少都被Scala学去了,个人觉得太复杂了,没
: 必要。
: OOP的其他两个所谓的特征,一个是继承,这个在OOP中都已经不太鼓励了,就不提也罢
: ;另一个是封装,这个其实是为了对付mutable数据的问题而不得不弄出来的一个枷锁
: 。如果数据是immutable的,这个枷锁是完全可以被去掉,这让数据得到解放,编程更

avatar
j*v
30
追求简洁是人类不断进步的动力,c有没有实际意义,汇编都能做,多几行代码而已

【在 f*******t 的大作中提到】
: 这篇文章只是试图用例子证明FP比DP简洁,但并没有任何实际意义,不就少写几行代码
: 么。
: 我只想知道有没有著名的FP工程(比如用Scala写的Kafka和Spark),正好有用OOP写的
: 替代品,两者比一下性能、维护难度和开发难度,就很容易看出FP吹的到底是货真价实
: 还是宗教信仰。

avatar
s*w
31
这个我是同意的。
但另一方面,生活中闲聊某个人,她身高三围,有工作吗?会做菜吗?这样把property
and function bind together是非常正常的思路。

【在 N*****r 的大作中提到】
: 另外我不明白为什么要把oop 和 fp放在一起讲
: 根本不是一个level的东西
: oop本质上目前还是过程式语言,但不代表函数式编程里就不能有OOP, 实际上用
: scheme就能模拟出一套oop的系统, 这是SICP里讲过的基础知识

avatar
T*x
32
那有没有immutable oop?

【在 h*i 的大作中提到】
: 如果你说的OOP的着眼点只是建立一个common interface,也就是所谓的多态,
: polymophism,这个FP也做,而且作得更灵活直观,也不需要使用繁复的各种design
: pattern来实现。比如Clojure,就有defprotocol, deftype,defrecord这些类似机制
: 来定义common interface。这些机制其实都是dispatch by type。 FP还有其他的机制
: ,比如multimethod, 可以dispatch by anything。 在Common Lisp里面,还有其他更
: 多的机制,比如mixins, traits之类,不少都被Scala学去了,个人觉得太复杂了,没
: 必要。
: OOP的其他两个所谓的特征,一个是继承,这个在OOP中都已经不太鼓励了,就不提也罢
: ;另一个是封装,这个其实是为了对付mutable数据的问题而不得不弄出来的一个枷锁
: 。如果数据是immutable的,这个枷锁是完全可以被去掉,这让数据得到解放,编程更

avatar
s*w
33
谢谢大家的讨论,我的问题不清楚是因为我没有理解。
目前是这样的,我们组写Javascript ES6坚决不肯用class,就像你们说的把function
传来传去,也许我们用法不对,我们写common interface时没有base class, 基本就是
2个js文件当作2个derived class, 里面有很多一样名字的function而已, 不像以前有
c++ has class hierarchy, 有个专门的base class.
然后我去读
https://stackoverflow.com/questions/30783217/why-should-i-use-es6-classes
有个人分别用ES6 class, ES5 function写了2个例子,我硬是看不出有啥区别,除了
class更清晰易懂。

【在 n***p 的大作中提到】
: yes, red is data, and it is not a function,
: you are mixing up oop with object. They are not the same.
: oop is about encapsulation, inheritance, and polymorphism, which all these
: so called great features are useless(see my last post) for FP, the pure FP
: language can do all OOP design patterns so easily and naturally.

avatar
s*w
34
对,肯定是各有各自的用处。

【在 g****t 的大作中提到】
: Simulink连几条线,控制个电机速度什么的。那就是信号被几个复合函数处理。就是函
: 数式的。input signal,output signal是单独的控件。没有内存,状态等东西。
: 但是你要写个GUI,页面上几十个地方可以输入输出。那oo更方便些。
:
:
: 请这里支持Functional Programming的大牛们讲讲例子,教育一下大家。
:

avatar
n*p
35
In oop, person三围变了,it is same person.
It's not the case for FP like clojure, it's not the same person if 三围
changes.
You think "正常"的思路, 在clojure programmer眼里不正常,we like to deal with
immutable object all the time.

property

【在 s*****w 的大作中提到】
: 这个我是同意的。
: 但另一方面,生活中闲聊某个人,她身高三围,有工作吗?会做菜吗?这样把property
: and function bind together是非常正常的思路。

avatar
n*p
36
That's why I said hybrid languages are not good for learning fp.
Scala at least let you pick between val and var, JavaScript obj almost
always mutable.

function

【在 s*****w 的大作中提到】
: 谢谢大家的讨论,我的问题不清楚是因为我没有理解。
: 目前是这样的,我们组写Javascript ES6坚决不肯用class,就像你们说的把function
: 传来传去,也许我们用法不对,我们写common interface时没有base class, 基本就是
: 2个js文件当作2个derived class, 里面有很多一样名字的function而已, 不像以前有
: c++ has class hierarchy, 有个专门的base class.
: 然后我去读
: https://stackoverflow.com/questions/30783217/why-should-i-use-es6-classes
: 有个人分别用ES6 class, ES5 function写了2个例子,我硬是看不出有啥区别,除了
: class更清晰易懂。

avatar
s*w
37
可能是这样,反正Javascript里的 function对我看起来就是个 class, 我硬是看不出
区别,有谁知道的多讲讲?

【在 n***p 的大作中提到】
: That's why I said hybrid languages are not good for learning fp.
: Scala at least let you pick between val and var, JavaScript obj almost
: always mutable.
:
: function

avatar
w*m
38
class提供给function更高一点的scope,方便管理function和变量。
像JS里面需要搞生命周期管理的,还是要用class。
avatar
h*i
39
如果数据是immutable的,OOP就只剩下多态有意义,这也就是Clojure里面的
defprotocol,defrecord之类机制,可用来作类似OOP的编程。这种类OOP编程方式,在
Clojure 里面,一般用来写库,在Clojure的一些高手写的库中很普遍。但是,应用程
序编程一般不用这种编程方式,而是直接用裸的immutable数据结构进行FP编程。
这个现象其实是符合不同编程用途的抽象水平的:FP抽象水平比较高,离机器远,适合
应用编程,OOP抽象水平更低,离机器近,适合底层库编程。
具体来说,用类OOP方式写库,一是库的需求一般比较明了,对多态的需求比较旺盛,
OOP还提供一些type guanrantee;二是为了性能。普通的Clojure immutable数据结构
功能大而全,不如自己手写数据结构控制一切来得精简。
所以Clojure的水平近阶,往往是这样的:在初学的时候,unlearn OOP,试图忘记以前
是如何编程的,学会完全不用赋值和循环来编程,这就到了中级水平,可以成为一个
Clojure应用程序员了;然后再把一些高级特性,transducer, reducers, core.async
,core.spec,之类的库熟悉掌握了,再把macro用溜,这就是一个高级Clojure应用程
序员了;最后,要开始写库给别人用,这就又要把OOP多态捡回来,这就是一个成熟的
Clojure专家了。这样的人,一般在社区里面也是有名有姓的人了,哈哈。

【在 T*******x 的大作中提到】
: 那有没有immutable oop?
avatar
f*t
40
追求简洁不一定带来好结果,比如golang比起c是很大的进步,ruby就是渣

【在 j*****v 的大作中提到】
: 追求简洁是人类不断进步的动力,c有没有实际意义,汇编都能做,多几行代码而已
avatar
T*x
41
defrecord从名字来看似乎是把简单类型组合起来命名,这和oop的封装有类似的效果。
给结构命名,即使在全immutable程序语言中也是有意义的。oop的封装不仅是为了掩盖
mutable数据(实际上比如python的class是掩盖不了内部数据的),也是给结构命名。
把结构叫做class或者object,这也是很自然的吧?

【在 h*i 的大作中提到】
: 如果数据是immutable的,OOP就只剩下多态有意义,这也就是Clojure里面的
: defprotocol,defrecord之类机制,可用来作类似OOP的编程。这种类OOP编程方式,在
: Clojure 里面,一般用来写库,在Clojure的一些高手写的库中很普遍。但是,应用程
: 序编程一般不用这种编程方式,而是直接用裸的immutable数据结构进行FP编程。
: 这个现象其实是符合不同编程用途的抽象水平的:FP抽象水平比较高,离机器远,适合
: 应用编程,OOP抽象水平更低,离机器近,适合底层库编程。
: 具体来说,用类OOP方式写库,一是库的需求一般比较明了,对多态的需求比较旺盛,
: OOP还提供一些type guanrantee;二是为了性能。普通的Clojure immutable数据结构
: 功能大而全,不如自己手写数据结构控制一切来得精简。
: 所以Clojure的水平近阶,往往是这样的:在初学的时候,unlearn OOP,试图忘记以前

avatar
s*V
42
跟世界本质无关,世界本质量子力学上面有薛定谔图景说量子态在演化,还有海森堡图
景态不动,是算符在演化。
OOP是一种社会化大分工的思维方式。
好的OOP,是一个class,你一开始把什么input都拿过来,instantiate以后就基本不用
用户管了,后面你就调一些简明的API就可以了。而函数式编程,每个函数基本都要一
堆输入,用户还是要有相当的domain knowledge才行。OOP,社会化大分工,每个人把
自己这块搞好,熟能生巧,凑起来就是好产品。

【在 h*i 的大作中提到】
: 如果数据是immutable的,OOP就只剩下多态有意义,这也就是Clojure里面的
: defprotocol,defrecord之类机制,可用来作类似OOP的编程。这种类OOP编程方式,在
: Clojure 里面,一般用来写库,在Clojure的一些高手写的库中很普遍。但是,应用程
: 序编程一般不用这种编程方式,而是直接用裸的immutable数据结构进行FP编程。
: 这个现象其实是符合不同编程用途的抽象水平的:FP抽象水平比较高,离机器远,适合
: 应用编程,OOP抽象水平更低,离机器近,适合底层库编程。
: 具体来说,用类OOP方式写库,一是库的需求一般比较明了,对多态的需求比较旺盛,
: OOP还提供一些type guanrantee;二是为了性能。普通的Clojure immutable数据结构
: 功能大而全,不如自己手写数据结构控制一切来得精简。
: 所以Clojure的水平近阶,往往是这样的:在初学的时候,unlearn OOP,试图忘记以前

avatar
h*i
43
OOP与社会化大分工没啥关系。OOP用在API上是很不合适,同时也很不成功的。
社会化大分工成功的是JSON,REST API这些简单直接,直接面向数据的东西。完全不管
啥数据模型,其实就是用些map, array,set之类基本数据结构组合起来就够了。这种
基于数据的搞法,FP是绝配,数据进,数据出,直接了当,不用试图对世界进行复杂的
建模,搞啥OOD,UML之类。这也是现在FP兴起的原因之一,各种语言里面用FP都不是什
么怪事了。
而SOAP,J2EE,UML之类想要解决同样的问题的OOP办法都失败了。

【在 s*****V 的大作中提到】
: 跟世界本质无关,世界本质量子力学上面有薛定谔图景说量子态在演化,还有海森堡图
: 景态不动,是算符在演化。
: OOP是一种社会化大分工的思维方式。
: 好的OOP,是一个class,你一开始把什么input都拿过来,instantiate以后就基本不用
: 用户管了,后面你就调一些简明的API就可以了。而函数式编程,每个函数基本都要一
: 堆输入,用户还是要有相当的domain knowledge才行。OOP,社会化大分工,每个人把
: 自己这块搞好,熟能生巧,凑起来就是好产品。

avatar
h*i
44
class,object啥的用在底层,处理与机器有关的事务,比如component lifecycle啥的
,是有效的。
用在应用程序高层逻辑就是脱裤子放屁,或者是自套枷锁。因为类型这种东西,在人的
世界里是不存在。计算机的类型必须自洽才能工作,而人的需求的类型,是经常变化的
,甚至是是不自洽的。其实看看任何大公司的API, 包括F G 这种一等大厂的API,都
是一坨屎,为什么?因为人的世界,是现实存在的屎一样的世界,与机器的纯粹世界两
码事。
所以程序猿关心的类型啥的,在point-hair boss (PHB)眼里,屁都不是,他们不care
。程序猿其实完全不用自虐,PHB要什么,就给什么的话,没有什么比用纯数据来编程
更容易的办法了。
所以屎一样的Javascript, PHP,JSON, REST等等,征服了世界。

【在 T*******x 的大作中提到】
: defrecord从名字来看似乎是把简单类型组合起来命名,这和oop的封装有类似的效果。
: 给结构命名,即使在全immutable程序语言中也是有意义的。oop的封装不仅是为了掩盖
: mutable数据(实际上比如python的class是掩盖不了内部数据的),也是给结构命名。
: 把结构叫做class或者object,这也是很自然的吧?

avatar
h*i
45
给结构命名不需要封装,也不需要类型。
多态的需求,本质上是解决代码重用的问题,这其实是一个底层的实现细节方面的需求
,与应用无关。
应用才不管你下面是如何实现的,是不是代码重用很好之类的问题。
可见,OOP的特性本质上与应用是完全无关的。但教科书为了显得有道理,非得把OOP这
些特性说成是因为应用,更有甚者,说成是世界的本质,这就是误人子弟的典型了。

【在 T*******x 的大作中提到】
: defrecord从名字来看似乎是把简单类型组合起来命名,这和oop的封装有类似的效果。
: 给结构命名,即使在全immutable程序语言中也是有意义的。oop的封装不仅是为了掩盖
: mutable数据(实际上比如python的class是掩盖不了内部数据的),也是给结构命名。
: 把结构叫做class或者object,这也是很自然的吧?

avatar
s*V
46
往玄里面扯,这就是唯心主义跟唯物主义的争论。OOP是唯心主义,FP是唯物主义。
社会化大分工就是每人管好自己的事情,你买个电视回来,只要会插电,用遥控器就可
以了。JSON,REST API这只是一种数据形式,跟OOP不是一个层面的东西。OOP是自有资
本主义思想在编程里面的体现,每个人把自己这一块做好做精做到最高效率。
但是实际应用里面,感觉FP是一个更局部使用的概念。世界上的数据种类千千万万,FP
怎么统一。只有局限在一个小的领域,大家都用类似的数据形式JSON啥的,进出都差不
多。

【在 h*i 的大作中提到】
: OOP与社会化大分工没啥关系。OOP用在API上是很不合适,同时也很不成功的。
: 社会化大分工成功的是JSON,REST API这些简单直接,直接面向数据的东西。完全不管
: 啥数据模型,其实就是用些map, array,set之类基本数据结构组合起来就够了。这种
: 基于数据的搞法,FP是绝配,数据进,数据出,直接了当,不用试图对世界进行复杂的
: 建模,搞啥OOD,UML之类。这也是现在FP兴起的原因之一,各种语言里面用FP都不是什
: 么怪事了。
: 而SOAP,J2EE,UML之类想要解决同样的问题的OOP办法都失败了。

avatar
h*i
47
你在往玄里面扯,唯心主义都出来了,一般这种我都不予置评。
我完全在扯编程的现实问题。说的就是如何管好自己的事情。
FP其实是完全不关心数据种类统一不统一的问题,不关心类型,只关心如何操作一些基
本的数据结构,map, list, set, vector。这就完了。既然程序输入输出都是这些数据
,你搞啥OOP类型啥的不是自己找不痛快么?没有必要。自己这块做好为啥要搞些没必
要的不存在的东东?做好做精做到最高效率也没有必要搞出类型这些玩意来。更何况,
直接用别人写好的高效率优化过的操作数据的函数,可能比自己搞一堆类型,每个类型
内部都是手写一堆for loops,mutable variables要更高效得多,无论是从程序员编程
效率还是程序的执行效率来说。

FP

【在 s*****V 的大作中提到】
: 往玄里面扯,这就是唯心主义跟唯物主义的争论。OOP是唯心主义,FP是唯物主义。
: 社会化大分工就是每人管好自己的事情,你买个电视回来,只要会插电,用遥控器就可
: 以了。JSON,REST API这只是一种数据形式,跟OOP不是一个层面的东西。OOP是自有资
: 本主义思想在编程里面的体现,每个人把自己这一块做好做精做到最高效率。
: 但是实际应用里面,感觉FP是一个更局部使用的概念。世界上的数据种类千千万万,FP
: 怎么统一。只有局限在一个小的领域,大家都用类似的数据形式JSON啥的,进出都差不
: 多。

avatar
d*c
48
回帖里太多太高深的东西了,要么哲学,要么太深,对你理解FP作用不大
不用考虑哲学,每个人都说的有道理,看看实际的区别,为什么要搞FP
1. FP和OOP封装的粒度和层次不同。
假设你给不同类型数据写排序函数,按OO可能把sort弄成每个类私有的,没法公用。用
继承多态搞重用会复杂,用FP的方式要简单很多。有的地方你需要留一点灵活性,比如
排序的比较过程,对不同数据可能需要不同的实现(字符串比较,数值比较,自定义数
据结构比较,比如一个复数你只比较实数部分,一个tuple你只比较第一部分),这时
把函数作为参数,就能在调用的时候把比较函数作为参数传进去(所谓的function as
first class object),但是整个排序函数的框架可以重用。
2. 第二点和OOD关系不大,属于过程性编程和FP编程的区别。
假设有个问题,你可以一边扫描一边排序一边做某些操作,这样只用扫一遍,节省一点
时间。但是用FP的方法,可以先排序,再做一个操作,再做一个操作。这样要扫描多次
,空间占用也多,但是对于程序员思维的解放是巨大的。
一边扫描一边做操作,你是把好几件事混在一起,需要维持状态的正确。分开一遍一遍
做,每一件事都可以很简单,可以用现成库或者现有函数,而且每件事很容易测试和保
证正确性。这对程序员都是更方便。实际上那点性能损失可以通过其他方式弥补,比如
高性能的专门优化的排序函数库不比你手写强吗?有可能上并行不是更好嘛?
3. 和第二点相关的,还是函数的独立性,减少耦合。
没有全局变量,所有数据通过参数传进来,所有数据通过参数传出去,不做in place
modification,有些时候看起来比直接修改,使用全局变量要多耗空间,性能有损失,
写法上稍微繁琐一些,但是同样带来程序员思维的解放。你只需要考虑一个函数局部,
一个纯函数拿到哪里用都可以,不用考虑全局的相互影响,这种减少耦合是系统设计的
最高目标之一。
而且通过immutable data structure,实际上不直接修改也不代表每次都要复制一遍。

【在 s*****w 的大作中提到】
: data and functions combo, 这又有啥问题?
: 如果是数学公式,我完全支持FP。
: 但这世界是由object构成的,家里前门是红色的,这个红色就是data,就跟这扇门联系
: 在一起,有啥问题?
:
: is

avatar
m*r
49
请教dracodoc (david)
你说'每件事很容易测试' , 我怎么觉得不容易测试? 函数式编程很容易一个函数套
另外一个函数, 很容易用到closure, closure就是函数生成的函数,看不见摸不着,
里面的变量,x,y,z,也不能打出来让人看,比黑盒子还要黑,所以我认为不容易测试。
再举个例子,用continuation_pass_style计算阶乘, 5!, 7! 如果你脑子好,可能不
需要debug, 写起来也就5,6行, 可你脑子不好,想看看每回调用是怎么回事,把‘函
数生成的函数’ 打印出来, 就难了。
你说'所有数据通过参数传进来,所有数据通过参数传出去', 传个快递容易, 传个集
装箱一样的大数据,请问怎么传? 在加上‘不可变性‘ ,如何操作?
avatar
d*c
50
我说的意思是每个函数要做的事情是单一的,不用考虑其他因素。一个函数测试好了,
不会因为其他函数的变化而受影响。有全局变量的话这点无法保证。
函数套函数强调的是high order function,只是FP的一个小部分。closure我的理解是
函数带上它周围的环境,lexical scoping以后不是纯函数了, 对于我强调的来说实际
反面例子。
要测试,我都是在R里加个browser(),交互式,测试很容易。当然这是调试,不是unit
test。你以前举得closure的例子我记得是专门弄得比较confusing为了区分一些细节
,至少我是不会那么写的。那些例子我认为不是好例子。
传递大数据,仅仅是读取的话不是问题,实际只是把引用传过去,关键是不能直接修改
。R是copy on modification,也就是只读的时候都是传递引用,需要修改时才创建副
本,然后改副本。
data.table则是一般直接改,所以能做到速度更快,占用内存更少。在速度,内存是限
制因素的时候还是得用直接改的方式,因为根本没条件一修改就复制。
在速度,内存不是限制因素的时候,多花点资源,程序员思考起来省事。然后通过底层
库提高性能来弥补,还是让程序员省心。
immutable data structure是专门解决这种问题的,你可以看看clojure相关的文章,
基于某个人博士论文之后的发展。非常简化的说,就是每次修改记录成日志,每次修改
的版本是历史,再也不变。这样多个函数实际可以共享同一个数据结构的不同版本,存
储上也不用复制。具体实现上还有许多细节。
java的string,R的string早期有一点相似性,immutable,每个string产生以后就不会
变,你的modification实际是复制了(这点不一样),这样一个string只用存一份,可
以被共享。

【在 m******r 的大作中提到】
: 请教dracodoc (david)
: 你说'每件事很容易测试' , 我怎么觉得不容易测试? 函数式编程很容易一个函数套
: 另外一个函数, 很容易用到closure, closure就是函数生成的函数,看不见摸不着,
: 里面的变量,x,y,z,也不能打出来让人看,比黑盒子还要黑,所以我认为不容易测试。
: 再举个例子,用continuation_pass_style计算阶乘, 5!, 7! 如果你脑子好,可能不
: 需要debug, 写起来也就5,6行, 可你脑子不好,想看看每回调用是怎么回事,把‘函
: 数生成的函数’ 打印出来, 就难了。
: 你说'所有数据通过参数传进来,所有数据通过参数传出去', 传个快递容易, 传个集
: 装箱一样的大数据,请问怎么传? 在加上‘不可变性‘ ,如何操作?

avatar
m*u
51
定义上,object 包含了整个世界;function 。。。。 还能比整个世界还大? :)
avatar
g*t
52
用git类似的办法管数据就可以了大多数情况下不改了吧。基本上git的命令很少操作到
原始文件。
但是绝对的不改数据我觉得是很有难度的。也没那个必要。

unit

【在 d******c 的大作中提到】
: 我说的意思是每个函数要做的事情是单一的,不用考虑其他因素。一个函数测试好了,
: 不会因为其他函数的变化而受影响。有全局变量的话这点无法保证。
: 函数套函数强调的是high order function,只是FP的一个小部分。closure我的理解是
: 函数带上它周围的环境,lexical scoping以后不是纯函数了, 对于我强调的来说实际
: 反面例子。
: 要测试,我都是在R里加个browser(),交互式,测试很容易。当然这是调试,不是unit
: test。你以前举得closure的例子我记得是专门弄得比较confusing为了区分一些细节
: ,至少我是不会那么写的。那些例子我认为不是好例子。
: 传递大数据,仅仅是读取的话不是问题,实际只是把引用传过去,关键是不能直接修改
: 。R是copy on modification,也就是只读的时候都是传递引用,需要修改时才创建副

avatar
f*t
53
OOP有两个层面,一层是封装数据,一层是封装程序结构,体现了人类的正常思维。以
输入输出都是基本数据结构为理由,认为处理的时候转成object是无用的,只是宗教信
仰而已。
avatar
c*v
54
第二条一小点补充。
有的for loop很难写成函数相接的形式。
有的函数相接的形式很难写成for loop。

as

【在 d******c 的大作中提到】
: 回帖里太多太高深的东西了,要么哲学,要么太深,对你理解FP作用不大
: 不用考虑哲学,每个人都说的有道理,看看实际的区别,为什么要搞FP
: 1. FP和OOP封装的粒度和层次不同。
: 假设你给不同类型数据写排序函数,按OO可能把sort弄成每个类私有的,没法公用。用
: 继承多态搞重用会复杂,用FP的方式要简单很多。有的地方你需要留一点灵活性,比如
: 排序的比较过程,对不同数据可能需要不同的实现(字符串比较,数值比较,自定义数
: 据结构比较,比如一个复数你只比较实数部分,一个tuple你只比较第一部分),这时
: 把函数作为参数,就能在调用的时候把比较函数作为参数传进去(所谓的function as
: first class object),但是整个排序函数的框架可以重用。
: 2. 第二点和OOD关系不大,属于过程性编程和FP编程的区别。

avatar
N*r
55

有递归在,怎么都能搞定

【在 c*******v 的大作中提到】
: 第二条一小点补充。
: 有的for loop很难写成函数相接的形式。
: 有的函数相接的形式很难写成for loop。
:
: as

avatar
N*r
56
OO这个思想真是没什么高深的,甚至说实话用处不大
OO最大的好处大概就是能把数据按关系聚合,然后能够根据数据类型做多态,限制函数
的域
但前者一般的structure就能解决, 后者范型更强大,而范型实际就是FP的一部分
OO之所以这么火,主要是通过OO限制了单个程序员的发挥空间, 使一个bug垮系统的事
情减少了, 表面上比FP好一点,但实际上该炸的bug还是会垮系统
avatar
c*v
57
理论上是如此。现实中很有难度。
可能是奥赛题那种难度。不是一般中老年适合的。

【在 N*****r 的大作中提到】
: OO这个思想真是没什么高深的,甚至说实话用处不大
: OO最大的好处大概就是能把数据按关系聚合,然后能够根据数据类型做多态,限制函数
: 的域
: 但前者一般的structure就能解决, 后者范型更强大,而范型实际就是FP的一部分
: OO之所以这么火,主要是通过OO限制了单个程序员的发挥空间, 使一个bug垮系统的事
: 情减少了, 表面上比FP好一点,但实际上该炸的bug还是会垮系统

avatar
h*i
58
的确是这样的。
其实递归很自然,更简单,比loop简单,教过小盆友就知道了。
我搞的DSL里面很多递归,但没有loop,文科小妞玩得很顺,初中生也一样玩得很顺。

【在 N*****r 的大作中提到】
: OO这个思想真是没什么高深的,甚至说实话用处不大
: OO最大的好处大概就是能把数据按关系聚合,然后能够根据数据类型做多态,限制函数
: 的域
: 但前者一般的structure就能解决, 后者范型更强大,而范型实际就是FP的一部分
: OO之所以这么火,主要是通过OO限制了单个程序员的发挥空间, 使一个bug垮系统的事
: 情减少了, 表面上比FP好一点,但实际上该炸的bug还是会垮系统

avatar
h*i
59
OOP主要的问题,是把一个功能打散,分到了各个不同的类里面,动一个地方,不知道
对其他地方会带来什么效应,因为其他的地方也能改这个类的东西,改了你还不知道。
理解一个OOP程序是如何工作的,需要很长时间。
基于immutable data的FP,完全没有这个问题,功能集中,就在一个函数里面,这个函
数改了,不用担心有没想到的效应,只要看看什么地方用到了这个函数的输出就行了。
代码没有副作用,理解起来容易太多了。

【在 N*****r 的大作中提到】
: OO这个思想真是没什么高深的,甚至说实话用处不大
: OO最大的好处大概就是能把数据按关系聚合,然后能够根据数据类型做多态,限制函数
: 的域
: 但前者一般的structure就能解决, 后者范型更强大,而范型实际就是FP的一部分
: OO之所以这么火,主要是通过OO限制了单个程序员的发挥空间, 使一个bug垮系统的事
: 情减少了, 表面上比FP好一点,但实际上该炸的bug还是会垮系统

avatar
h*i
60
如果数据是不可变的,大家随便读,反正也改不了。要改自己建一个新的,原来的不变
,所以就不必要封装了。
组织程序的结构也不需要用类来封装,用命名空间namespace就够了,无非是把相关的
函数放在一个命名空间里,便于引用而已,封装是不必要的。
OOP把很多不想关的考虑混在一起,弄出了不必要的限制,要干点事有很多仪式,
deisgn pattern啥的,禁锢思想。
好好的数据,转成object还真没有什么用处。否则也不用说啥“OOP体现了人类的正常
思维”,凡是不符合OOP的,就不是正常人类思维了么?这其实完全就是宗教信仰的说
法了。把异端都打成非人的,这不是极端宗教思维的特征么?

【在 f*******t 的大作中提到】
: OOP有两个层面,一层是封装数据,一层是封装程序结构,体现了人类的正常思维。以
: 输入输出都是基本数据结构为理由,认为处理的时候转成object是无用的,只是宗教信
: 仰而已。

avatar
h*i
61
说得很好。

as

【在 d******c 的大作中提到】
: 回帖里太多太高深的东西了,要么哲学,要么太深,对你理解FP作用不大
: 不用考虑哲学,每个人都说的有道理,看看实际的区别,为什么要搞FP
: 1. FP和OOP封装的粒度和层次不同。
: 假设你给不同类型数据写排序函数,按OO可能把sort弄成每个类私有的,没法公用。用
: 继承多态搞重用会复杂,用FP的方式要简单很多。有的地方你需要留一点灵活性,比如
: 排序的比较过程,对不同数据可能需要不同的实现(字符串比较,数值比较,自定义数
: 据结构比较,比如一个复数你只比较实数部分,一个tuple你只比较第一部分),这时
: 把函数作为参数,就能在调用的时候把比较函数作为参数传进去(所谓的function as
: first class object),但是整个排序函数的框架可以重用。
: 2. 第二点和OOD关系不大,属于过程性编程和FP编程的区别。

avatar
x*4
62
我把你的说法在转述一下:
用immutable data的fp一个最重要的特性是referential transparency,即是,一个
expression,在任何环境下evaluate得到的结果都是一样的,完全不依赖于环境和side
effect。所以你要做修改和debug的时候是完全不需要理解你要改的函数以外的任何
code。我觉得这点比oop的封装更强,写出来的code更容易理解和修改。

【在 h*i 的大作中提到】
: OOP主要的问题,是把一个功能打散,分到了各个不同的类里面,动一个地方,不知道
: 对其他地方会带来什么效应,因为其他的地方也能改这个类的东西,改了你还不知道。
: 理解一个OOP程序是如何工作的,需要很长时间。
: 基于immutable data的FP,完全没有这个问题,功能集中,就在一个函数里面,这个函
: 数改了,不用担心有没想到的效应,只要看看什么地方用到了这个函数的输出就行了。
: 代码没有副作用,理解起来容易太多了。

avatar
h*i
63
是这样。
所以FP也讲究bottom-up, REPL driven编程, 一个一个小函数单独测试实验,不用管
其他的东西。写起来容易,改起来也容易。还有就是代码短,虫子就少。
总的来说,是一种很不同的编程体验。
以前写Java的时候,经常是写了一个星期了,程序还一次都没有运行过,感觉是在写文
章。现在写Clojure的时候是不停在运行一个个的小函数,更接近用R notebook的味道。

side

【在 x***4 的大作中提到】
: 我把你的说法在转述一下:
: 用immutable data的fp一个最重要的特性是referential transparency,即是,一个
: expression,在任何环境下evaluate得到的结果都是一样的,完全不依赖于环境和side
: effect。所以你要做修改和debug的时候是完全不需要理解你要改的函数以外的任何
: code。我觉得这点比oop的封装更强,写出来的code更容易理解和修改。

avatar
T*x
64
我再把你的说法转述一下:用immutable data的programming language 一个最重要的
特性是referential transparency,即是,一个expression,在任何环境下evaluate得
到的结果都是一样的,完全不依赖于环境和side effect。所以你要做修改和debug的时
候是完全不需要理解你要改的函数以外的任何code。我觉得这点比mutable data的封装
更强,写出来的code更容易理解和修改。

side

【在 x***4 的大作中提到】
: 我把你的说法在转述一下:
: 用immutable data的fp一个最重要的特性是referential transparency,即是,一个
: expression,在任何环境下evaluate得到的结果都是一样的,完全不依赖于环境和side
: effect。所以你要做修改和debug的时候是完全不需要理解你要改的函数以外的任何
: code。我觉得这点比oop的封装更强,写出来的code更容易理解和修改。

avatar
f*t
65
现实世界有很多constant,也有很多变量,强行要求数据不可变,不是宗教信仰是什么?
比如你举的例子,一个vector,改其中一个元素的值,非要返回一个新的vector。不管
怎么优化背后的操作,都增加了不必要的复杂度,按你的原话说就是“弄出了不必要的
限制,要干点事有很多仪式”。直到分布式系统机器间分享状态有困难,才考虑把数据
变成immutable并多做一些处理的tradeoff。不应该教条地从一开始就规定数据
immutable。
我所说的oop,是尊重自然的灵活的编程思想。不变的东西不用变,会变的数据提供一
个指针让大家改。需要共享状态的函数封装在一起,而不是为了FP强行去想trick分开。

【在 h*i 的大作中提到】
: 如果数据是不可变的,大家随便读,反正也改不了。要改自己建一个新的,原来的不变
: ,所以就不必要封装了。
: 组织程序的结构也不需要用类来封装,用命名空间namespace就够了,无非是把相关的
: 函数放在一个命名空间里,便于引用而已,封装是不必要的。
: OOP把很多不想关的考虑混在一起,弄出了不必要的限制,要干点事有很多仪式,
: deisgn pattern啥的,禁锢思想。
: 好好的数据,转成object还真没有什么用处。否则也不用说啥“OOP体现了人类的正常
: 思维”,凡是不符合OOP的,就不是正常人类思维了么?这其实完全就是宗教信仰的说
: 法了。把异端都打成非人的,这不是极端宗教思维的特征么?

avatar
j*a
66
there're atom/ref/agent/var in clojure.

么?
开。

【在 f*******t 的大作中提到】
: 现实世界有很多constant,也有很多变量,强行要求数据不可变,不是宗教信仰是什么?
: 比如你举的例子,一个vector,改其中一个元素的值,非要返回一个新的vector。不管
: 怎么优化背后的操作,都增加了不必要的复杂度,按你的原话说就是“弄出了不必要的
: 限制,要干点事有很多仪式”。直到分布式系统机器间分享状态有困难,才考虑把数据
: 变成immutable并多做一些处理的tradeoff。不应该教条地从一开始就规定数据
: immutable。
: 我所说的oop,是尊重自然的灵活的编程思想。不变的东西不用变,会变的数据提供一
: 个指针让大家改。需要共享状态的函数封装在一起,而不是为了FP强行去想trick分开。

avatar
j*a
67
and https://clojure.org/reference/transients

么?
开。

【在 f*******t 的大作中提到】
: 现实世界有很多constant,也有很多变量,强行要求数据不可变,不是宗教信仰是什么?
: 比如你举的例子,一个vector,改其中一个元素的值,非要返回一个新的vector。不管
: 怎么优化背后的操作,都增加了不必要的复杂度,按你的原话说就是“弄出了不必要的
: 限制,要干点事有很多仪式”。直到分布式系统机器间分享状态有困难,才考虑把数据
: 变成immutable并多做一些处理的tradeoff。不应该教条地从一开始就规定数据
: immutable。
: 我所说的oop,是尊重自然的灵活的编程思想。不变的东西不用变,会变的数据提供一
: 个指针让大家改。需要共享状态的函数封装在一起,而不是为了FP强行去想trick分开。

avatar
d*c
68
具体讨论技术就好,没必要上升到哲学高度。
非要从哲学角度讲,很多事情不是你想象那样直观。
你所谓的“变化“概念暗含着这样的假设:
- 比如说“变量”:某点的测量温度,随时间变化。
但这是你一定要用同一个量/名字/容器去标记不同的值的结果。某点在时刻A的测量值
和时刻B的测量值是两个不同的事件,人非要用同一个名字去描述,加上时间维度,形
成了变量概念。
把时间维度拆开,可以描述为一系列事件,但每个事件都是历史,都是不可变的。这里
不可变的是事实,是data。上面可变的变量并不是事实,而是人为的创造物。
我不是说变量不存在,或者人为创造变量概念没有道理,只是要说明变量概念是后加上
去的。
至于规定数据immutable的目的不是教条或者某些哲学上的纯粹性,而是为了程序员的
工作更轻松。当你面对的问题更加简化,减少全局变量,减少耦合时,对人的生产力是
提高。
这样做有代价,但是:
1. 机器性能的提高,让越来越多任务能用这种方法处理。
2. 通过类库去挽回一些--那会是很复杂的工作,但是一般人不需要考虑,少数人做好
了,所有人都受益,而且以后只要类库持续进步,所有程序就持续进步。clojure挂在
JVM上就是这个道理。
FP不能解决所有问题,比如前面提到过的,用户界面就无法避免耦合,很多复杂性是内
禀的。但是随着硬件和类库的发展,FP能解决越来越多的问题(比例增加未必很多,但
绝对数量会很多),这是大趋势。

么?
开。

【在 f*******t 的大作中提到】
: 现实世界有很多constant,也有很多变量,强行要求数据不可变,不是宗教信仰是什么?
: 比如你举的例子,一个vector,改其中一个元素的值,非要返回一个新的vector。不管
: 怎么优化背后的操作,都增加了不必要的复杂度,按你的原话说就是“弄出了不必要的
: 限制,要干点事有很多仪式”。直到分布式系统机器间分享状态有困难,才考虑把数据
: 变成immutable并多做一些处理的tradeoff。不应该教条地从一开始就规定数据
: immutable。
: 我所说的oop,是尊重自然的灵活的编程思想。不变的东西不用变,会变的数据提供一
: 个指针让大家改。需要共享状态的函数封装在一起,而不是为了FP强行去想trick分开。

avatar
f*t
69
"至于规定数据immutable的目的不是教条或者某些哲学上的纯粹性,而是为了程序员的
工作更轻松。当你面对的问题更加简化,减少全局变量,减少耦合时,对人的生产力是
提高。"
我主要就是不认同这点。
* 非FP不代表不能将一部分数据以immutable的方式去处理。
* 强行规定数据immutable并不能让程序员的工作更轻松和简化问题。
默认数据mutable,合理应用immutable策略,才是最高效的编程模式。

【在 d******c 的大作中提到】
: 具体讨论技术就好,没必要上升到哲学高度。
: 非要从哲学角度讲,很多事情不是你想象那样直观。
: 你所谓的“变化“概念暗含着这样的假设:
: - 比如说“变量”:某点的测量温度,随时间变化。
: 但这是你一定要用同一个量/名字/容器去标记不同的值的结果。某点在时刻A的测量值
: 和时刻B的测量值是两个不同的事件,人非要用同一个名字去描述,加上时间维度,形
: 成了变量概念。
: 把时间维度拆开,可以描述为一系列事件,但每个事件都是历史,都是不可变的。这里
: 不可变的是事实,是data。上面可变的变量并不是事实,而是人为的创造物。
: 我不是说变量不存在,或者人为创造变量概念没有道理,只是要说明变量概念是后加上

avatar
n*p
70
If you dealing with concurrency a lot, immutable data is much easy

【在 f*******t 的大作中提到】
: "至于规定数据immutable的目的不是教条或者某些哲学上的纯粹性,而是为了程序员的
: 工作更轻松。当你面对的问题更加简化,减少全局变量,减少耦合时,对人的生产力是
: 提高。"
: 我主要就是不认同这点。
: * 非FP不代表不能将一部分数据以immutable的方式去处理。
: * 强行规定数据immutable并不能让程序员的工作更轻松和简化问题。
: 默认数据mutable,合理应用immutable策略,才是最高效的编程模式。

avatar
h*i
71
你要讨论本质,让我来谈谈本质。
比如一个人,长大了,从一个小人变成了大人。从物理上看,这两个人完全不同了,是
两个不同的人。这个声明:“这个个小人和那个大人其实是同一个人”,*不是*不言自
明的。也许对看着他长大的人,这是一个事实(其实这都不一定,生过小孩就知道,生
怕别人把小孩调包了,所以小孩一出生医院都得在孩子脚上装标签,小孩拿回家才剪掉
),对别人,就不一定了。如果你非要说这两个人还是同一个人,这需要有很多其他的
证据,出生证,DNA啥的都得搞一遍。
上面说的没有疑问吧? 不是宗教信仰吧?
那么两个不同的东西,其实有同一个identity,这个自然现象,要在计算机上模拟,怎
么搞?
Imperative Programming (IP)的搞法是这样: 我们用计算机的内存地址的值来作
identity。同一个地址所指就是同一个东西。这看似很简单,但新东西总是会盖了旧东
西。在很多应用上,这是很难对付的问题。为啥?因为IP的做法其实是个抄近路的做法
,掩盖了事情的本质,
新旧东西物理上就是不同的,本质上,要证明两个不同的东西有相同的identity,必须
有其他的证据,而IP用内存地址来代表identity, 这是个模拟的实现细节,是模拟过程
本身自己加的东西,不是问题本身存在的特性,所以这不构成证明identity的证据,“
地址一样就是指向同一个东西”,是模拟实现个一个convention, 被模拟对象,人,本
身没有内存地址这个特性,只有DNA这种内部特性。
FP无非是不抄近路而已,不用地址来作identity,而是用名字。因为名字自己也有个地
址,这其实是用两层地址,而不是一个地址来代表一个东西。Clojure里面, var, atom
, ref, agent, 这些可变量,就是强迫你加上这一层indirection,来反映现实的本质。

么?
开。

【在 f*******t 的大作中提到】
: 现实世界有很多constant,也有很多变量,强行要求数据不可变,不是宗教信仰是什么?
: 比如你举的例子,一个vector,改其中一个元素的值,非要返回一个新的vector。不管
: 怎么优化背后的操作,都增加了不必要的复杂度,按你的原话说就是“弄出了不必要的
: 限制,要干点事有很多仪式”。直到分布式系统机器间分享状态有困难,才考虑把数据
: 变成immutable并多做一些处理的tradeoff。不应该教条地从一开始就规定数据
: immutable。
: 我所说的oop,是尊重自然的灵活的编程思想。不变的东西不用变,会变的数据提供一
: 个指针让大家改。需要共享状态的函数封装在一起,而不是为了FP强行去想trick分开。

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。