函数式编程的杂七杂八(非常乱)

1.把大象关进冰箱里问题

面向过程:

把大象关进冰箱里:
    把冰箱门打开=>
    大象放冰箱里=>
    冰箱门关上

面向对象:

冰箱.开门()
冰箱.放入(大象)
冰箱.关门()

函数式:

关进(冰箱,大象):
  关门(放入(开门(冰箱),大象))
——————————————————————————

2.

C#引入FP的特性被某些人称作语法糖,我一直有意把这种观点拖出来痛打一顿(注意不是把持有这种观点的人拖出来痛打),至于持有这种观点的人,我禁止你们写a+b*c,以后给我统统去写汇编
MOV  EAX, [b]
MUL  EAX, [c]
ADD  EAX, [a]

当然前提是我能禁止得了。

——————————————————————————

3.语言特性和编程范式完全是两码事

从某种程度上来说,C语言既能进行函数式编程,又能进行

在支持面向对象的语言里,我完全可以设计一个类似下面的类

class Search {
 virtual List Extend(Node node)
 virtual bool Beam(Node node)
 virtual bool CheckFinish(Node node)
 Node Search()
 {
  OrderedCollection openlist=new OrderedCollection();
  openlist.put(node);
  while(!openlist.empty()){
   Node current=openlist.get();
   if(!Beam(current)){
    List extended=Extend(current);
    for(var i=0;i<extended.length;i++)    {
     if(Finish(extended[i]))
      return extended[i];
     openlist.put(extended[i]);
    }
   }
  }
  return null;
 }
}

我甚至用到了一个设计模式:模板方法。

不过这个代码跟面向对象没有半点关系,我只是在利用某些语言特性而已。

对于任何一门编程语言而言 把class当成"类"这个意思都是程序员一厢情愿的想法——编译器才不在乎这个关键字是class还是glass,只是个关键字而已。

父亲们在这几这些语言的时候,当然是有意识地提醒你这个特性将被用于面向对象,但人家没有强迫你这样做。

于是某些不安分的同学(比如我),就喜欢拿面向对象特性来干一些不是面向对象的事,或者拿一些不是面向对象的特性来干面向对象的事情。


所以对于C而言 closure无非是比函数指针多了一个void*而已,多传一个参数又不会少块肉——你敢说这不是语法糖?

不过拿这样的方式来做FP确实闻所未闻,这从一个侧面说明了语言特性对于人的思维影响还是很大的。

所以尽量不要做那些扭着来语言特性来的事情,比如,用人家叫Exception的东西表达正常逻辑。

——————————————————————————

4.给10个按钮改变颜色

for(var i = 0 ; i < 10 ; i++ )
    button[i].background = XXXX;

这段简单的代码丢失了一个重要信息,那就是"给10个按钮改变颜色的顺序是不要求的"。

所以想这段代码翻译回去变成原来的语义是不能的。

但是函数式可以。

任何一个函数都不介意自己的参数被求值的顺序。

但是任何一个函数不会在自己参数被求值之前执行。

所以 放入(开门(冰箱),大象) 一定会在 开门(冰箱) 之后执行。

这些被丢掉的信息,在多核处理器中尤其重要。

你写

dotA();
dotB();

的时候,我肯定不知道doA和doB是否能并行执行。

但是

do(dotA(),dotB())

这时候,我肯定知道doA和doB可以同时做。

神啊 原谅我用dota做SEO吧......

——————————————————————————

5.范式是认识世界的方法论

使持续工作12小时(皮鞭抽(程序员),工作用计算机) ,

对于完成一个项目,有些老板是这样理解的;

皮鞭抽程序员=>勒令程序员用计算机工作=>等待完成

也有些老板是这样理解的。

当老板思考"如何完成工作"的时候,他们也许会使用完全不同的方法得到相同的结论。

这其实与编程无关,当你开始思考这世界的时候,一定会选择其一来理解世界。

函数式不算阳春白雪,其实你一直在用了。

世界上的是,无论你想做什么,无非是把一些东西变成另一些东西,这就是函数式编程的世界观。

只是你不习惯把这种思维用到程序中而已。

你总是想告诉计算机,先这样,再这样,然后那样。

所以如果你真正希望理解函数式,关键是观念的转变——你必须完全抛弃先后的想法。

posted @ 2010-07-02 19:55 winter-cn 阅读(...) 评论(...) 编辑 收藏