函数式编程的杂七杂八

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

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小时(皮鞭抽(程序员),工作用计算机) ,

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

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

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

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

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

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

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

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

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

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

资源下载链接为: https://pan.quark.cn/s/1bfadf00ae14 华为移动服务(Huawei Mobile Services,简称 HMS)是一个全面开放的移动服务生态系统,为企业和开发者提供了丰富的工具和 API,助力他们构建、运营和推广应用。其中,HMS Scankit 是华为推出的一款扫描服务 SDK,支持快速集成到安卓应用中,能够提供高效且稳定的二维码和条形码扫描功能,适用于商品扫码、支付验证、信息获取等多种场景。 集成 HMS Scankit SDK 主要包括以下步骤:首先,在项目的 build.gradle 文件中添加 HMS Core 库和 Scankit 依赖;其次,在 AndroidManifest.xml 文件中添加相机访问和互联网访问权限;然后,在应用程序的 onCreate 方法中调用 HmsClient 进行初始化;接着,可以选择自定义扫描界面或使用 Scankit 提供的默认扫描界面;最后,实现 ScanCallback 接口以处理扫描成功和失败的回调。 HMS Scankit 内部集成了开源的 Zxing(Zebra Crossing)库,这是一个功能强大的条码和二维码处理库,提供了解码、生成、解析等多种功能,既可以单独使用,也可以与其他扫描框架结合使用。在 HMS Scankit 中,Zxing 经过优化,以更好地适应华为设备,从而提升扫描性能。 通常,ScanKitDemoGuide 包含了集成 HMS Scankit 的示例代码,涵盖扫描界面的布局、扫描操作的启动和停止以及扫描结果的处理等内容。开发者可以参考这些代码,快速掌握在自己的应用中实现扫码功能的方法。例如,启动扫描的方法如下: 处理扫描结果的回调如下: HMS Scankit 支持所有安卓手机,但在华为设备上能够提供最佳性能和体验,因为它针对华为硬件进行了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值