扯一扯纯函数

函数式编程成了现在编程圈里越来越火的话题。我第一次听说函数式编程是在编译原理课上,那位巨牛逼的年轻老师用普林斯顿大学的教程向我们简单介绍了ML语言,那时候编程和数学基础都巨薄弱的我对“函数”两字产生了极大的恐惧,对于ML的语法完全无法理解。第一次意识到函数式编程是在网上哪篇文章里看到js的函数式编程能力(现在这种文章到处都是),我才发现我最常用的语言原来有这巨牛逼的能力,然后就沾沾自喜的以为自己就是函数式编程的程序员了。

呵呵,挺傻逼的。

js极度灵活,的确具有函数式编程的能力,但不是说写个内部函数,参数里传个函数或者返回个函数就是函数式编程了,这只是函数式编程的最低要求,所谓函数是一等公民。

后来学了一些clojure知道了还有个函数纯不纯的问题。

后来学了一点haskell知道了为函数式编程设计的语言调用函数是可以多么的优雅!

今天说的是纯函数,优雅明天说吧。

纯函数就是不会对外界产生影响的函数,这个外界不光是程序外界,而是函数的外界。所以haskell没有变量。一开始知道这个概念的时候感觉很恐怖。没有变量!!!那我岂不是没有地方保存我程序运行到每一步的结果了吗?比如我有个person,他age++了,如果这个person不是变量,那连age都没法++。的确,纯函数里,你给函数一个29岁的人,他会返回给你一个30岁的人,原来29岁的人还在那。这不科学啊,怎么平白无故多了个人呢!好吧,我要说,纯函数语言都不是面向对象的,就不要那那么具象的思维来思考了。可以怎么想,30岁的我已经不是29岁的我了。。。很沧桑的解释 -_-!

我想,函数式编程不是那么容易被接受就是因为它抽象。不管你是人也好是木头也好,对函数来说就是一个待加工的原件,函数负责产生一个新的成品,还不影响原来的,买一赠一不好么?

那这有什么好处呢?拿haskell最得意的话来说,安全。你永远无法改变一个已经存在的值,就意味着这个值可以在任何时候被你安全的使用,还可以被任何人安全的使用,这不就是并发里面最难以解决的问题吗。什么这锁那锁呀,既然没有变量,就不用锁了。暂且不说并发(作为js程序员,还真没法深入说并发),就说写自己的线性程序,经常会发生的错误是一个值已经被改变了,但是你没有意识到,还按照原来的方式去使用它,这种问题完全可以避免了,你要使用原来的值就是原来的值,要使用新值一定是通过一个函数加工过的值。

再怎么纯的函数式编程语言,还是要跟外界打交道的,要不然这个语言就没有存在的意义了。纯函数的语言会把不纯的地方单拎出来,一股脑的给你污染外界,而不是不停的污染外界,这样你就会更明白对外界做了什么。

举个例子对比一下。用jQuery进行dom操作,我最喜欢它的链式语法,query出来一个dom对象就开始使劲改变它,点一次变一点,.addClass一下加了个类名,.css一下变了个样式。。。函数式编程肯定不会这样,它一定会是拿到原来的dom对象,通过一串函数的加工,每次加工的结果是下一次加工的原料,而每次加工的结果都不对外界产生影响(这个结果是一个没有挂到页面上的东西),直到拿到最后一次加工的结果,才郑重的真正操作dom替换原来的元素,最可能的方法是直接写innerHTML。

嗯。。。不过这是我猜的,因为目前我还从来没用纯函数编程语言写过web脚本。但是这种语言是存在的,比如ELM,它是一种和Haskell语法很像的最终生成js、css和html代码的语言,它用到了一种叫做Virtual DOM的技术,原理就是不直接操作dom而是叫做虚拟dom的数据,这个数据当然不会直接改变dom(所以不直接改变它而是每次调用函数产生一个新的virtual dom是完全可以的),当需要真的改变dom的时候,系统会比较一下前后dom的最小差异,然后进行最小的修改,所以性能也是杠杠的。怎么样,这很贴合纯函数编程的思路吧?

原文地址:https://www.cnblogs.com/tolg/p/4652743.html