一直想为自己和小伙伴们总结一下现在的编程“新”特性,即函数式编程,然而奈何每天把大量的时间都分配给应付产品经理了。如今赶在国庆假期,忙里偷闲的把这个事情再次梳理一下。以方便今后日程当中少一个躺尸。
注:这只是一篇思维综述,不是具体的技术文章。
1.历史的界限已然划清
我常常把我们这批程序员以“JAVA后”来封号,这并非空穴来风。虽然看似博客上计算机领域高手如云,然而现实工作当中,以一招“JAVA”独步天下的大有人在,并非说我们这群小伙伴只是会敲JAVA,而更多表现在当谈论编程思想的时候,我们只会回答:“万物皆对象”,而当谈及应用架构时,我们必然高度概括为“MVC”。至少在2013年以来我所接触的程序员其实都是“JAVA后”,我们已经忘却图灵是谁,转而只是虔诚的信奉詹姆斯·高斯林——JAVA之父。
大约是十几年前,还是在C++与JAVA刚刚开始对垒的时候,JAVA因为其厚重的“身体”而还不被广泛接受,然而几年之后,随着计算机硬件领域的长足发展,人们已经不必担忧JVM过分消耗资源的时候,JAVA因为其简介的语法和良好的面向对象设计理念而备受关注,并在其后持续升温,以至于最终鼎立中原。并非说面向对象的思想仅仅是JAVA的产物,而是JAVA把程序员的思维真正意义上面向对象了。历史往往如此,当一个文化绝对鼎盛的时候,另一个文化就会“被”消亡。在时隔多年之后的今天,许许多多得人因为本专业等不到良好发展,而纷纷转投计算机领域。而这些人其伊始就是使用JAVA,因此“代沟”在不知不觉当中被早就,如今已是大部分普通程序员不可轻易逾越的鸿沟。
然而,就在我们欢欣鼓舞怒怼产品经理的时候,另一种思想已经悄然登上了历史舞台,这就是函数式编程,而如果仔细思索这个问题时,忽然有一种察觉,那就是历史可能又要重演了。
2.再述历史——图灵机以及早期命令式编程
一个计算机领域的人不熟悉阿兰图灵,那就像学物理的不熟悉艾萨克牛顿,学数学的没听过希尔伯特一般,要遭到同行耻笑。而阿兰图灵当年做的最牛的一大贡献就是创造了图灵机这个东西。理想图灵机模型由三部分主要的结构组成,一条无限长的纸带,一个能够读写信息的磁头以及一组固定在磁头当中的程序表。然后磁头负责IO读写并根据纸带信息对比程序表更新磁头自身的状态,并将新的信息写出到纸带。
当然,现在的程序员很多都没见过纸带、软盘这类存储介质了。所以用更新的说法来说,图灵机就是一部这样的机器,它从硬盘读取数据,然后根据芯片中封装好的指令,对数据进行处理并更新芯片自身的状态,最后再把新的数据写入的硬盘存储起来。怎么样,这么说是不是灵光一闪。没错,图灵机就是现代计算机的早期模型之一。当然至于诺依曼机时代我们这里就省略不谈了。
其实说到底,最初计算机的程序表,就是一个动作指令集合,在“JAVA后”能触及的范围来讲更接近于汇编语言。也就是说,早期的计算机语言包括两个集合,其一是指令集,其二是状态变量。这就是早期语言的基本点。有一种说法称之为命令式编程,当然JAVA也是命令式编程。但设计思想却有很大不同。
3.如今迈步——JAVA以及OOP设计思想
许多人在用JAVA,许多人在用OOP思想去设计程序。然而我们却没有那么深刻的了解程序。程序是计算机的语言,既然是语言就必然有它诞生的目的——即处理数据。从古至今,无论是算盘、算筹还是现当代的笔记本电脑,我们发明和发展计算机科学的唯一目的就是通过处理数据来解决一些现实问题。这是不可否认的事实。而这么多年,我们不过是在更新基础设施以及演进思维处理方法。
而因为受到物理介质基础的变革,OOP程序设计思想成为众多方法论中的一个翘楚。OOP即是对现实世界的一个优雅的抽象,它能够以十分自然的方式将数据进行组合并降低Exception的可能性。自然语义是计算机发展的一个重要方向,因为它能够大大简化人们对计算机语言的学习成本,从而让许多业务功能被更容易的处理和解决。JAVA是OOP众多语言中的一个典范,虽然C++已经能够实现OOP的诉求,但是由于指针回收等问题,使得现实工作当中在处理计算机自身问题上做出了太多的消耗成本,因此面临JAVA,Python等众多高级语言时,人们更容易接受和掌握该类语言。所以成就了一代“JAVA后”程序员的风华伟业。
但是,随着历史的推移,OOP再次暴露其本质问题,那就是如何高效的处理极高数量级的数据。虽然提出了机器学习等众多概念,但是面对宇宙洪荒,我们不得不再次思考起那些高大上的问题,即“双十一那么多访问和数据IO,那么多用户习惯数据,咋整啊?”
4.蓦然回首——FUNCTION程序设计思想
回首人类的古老文明,什么设计思想最适合处理大批数据量,什么语言适合优雅而完美的构建那些数据模型和处理算法?答案自然是数学。
计算机科学的演进永远不能够回避掉数学的论题,可以说数学才是这个领域之魂。所以从数学角度来阐释最佳的程序设计语言,自然是函数式程序设计思想。函数的基础是参数和映射关系,它能够高度契合程序设计需求。并且由于数学精准的语义定义,从而在根本上消除了Exception的可能性,又在此基础之上能够对模型进行高度抽象,使得任何表达都看起来如此简介且优雅。配合现在物理硬件的条件,也能够搞出那些所谓的高并发等性能优化。
如果说你还没注意到函数式编程是一个多么重要的问题,那么只能说你是一个多么宅的“JAVA后”程序员。因为你可能还没用过JAVA8的新特性,可能你的JS封装还很low。现如今,许多优秀的处理语言纷纷靠拢函数式程序设计思想,例如JAVA8中引入了Lamda表达式和Stream,JS和Nodejs越来越多的代码采用Lamda表达式以及Currying优化。Python、Matlab和Octave等语言则更是不必说,实在是生于斯且长于斯,如果你还尝试过Kotlin(新的Android一级语言)和F#(微软给出的ML函数程序设计语言)。你就会逐渐意识到,越来越多的语言还是使用函数式程序设计思想从而实现更为高度的优化和抽象,以满足如今高量级数据IO处理需求。
可能你会觉得这刚刚开始流行的东西,能走多远,又需要多久能普及。但事实上函数式编程思想并非什么新东西,早在图灵机提出之前,邱琪就已经完成了Lamda演算的大部分工作,虽然当时并未叱咤风云,名噪一时。但是因为Lamda演算能够完全等同于图灵机模型,所以冥冥之中注定它会成为历史长河中又一个宠儿。
最近解除了许多量化金融、比特币服务以及ML等业务场景,所以越发发现函数式程序设计思想的重要性。其实想要尽快的了解和掌握函数式程序设计思想并非难事,至少在实际工作中是这样的,你只需要将你的思维简单的会退到OOP之前一点,然后补充一点数学中所谓的形式主义,即符号系统和低阶逻辑即可。
5.总结
由于这仅仅是一篇感言,所以真的并不希望在这里进行任何技术上的说明,也不细致的讨论Lamda代数体系,当然如果未来能够少一些产品经理找麻烦,这些东西我还是要一一尝试去作为系列博客的。并非要超越那些大牛们,而仅仅是对我自己和小伙伴们的一点提醒和鼓励。
保持敏锐的嗅觉和精神吧,函数式编程的时代就要来了!!!