最近的以太坊漏洞现在有文章做了仔细的分析,纠其根本是基于图灵机的过程式语言与人类逻辑思维冲突的问题,今天就来聊聊函数式编程语言,这个非常古老可能未来会大热的编程语言体系。
首先,我们要明确函数式编程语言和函数式编程的区别,函数式编程是近来过程式语言吸收函数式编程语言的优点形成的一种编程风格,通过框架定义形成的类似函数式编程语言的风格,使得过程式语言(包括面向对象语言)具备某些函数式语言的特征,其核心还是过程式语言。
在计算机编程王国里面有两个重要语言,一个是C,一个是LISP,都是非常古老的语言。C语言相信大家都不陌生,C语言影响了后来很多语言的发展,包括C++,JAVA,C#,javascritp都可以看做是类C语言的延伸;LISP语言可能很多人就比较陌生了,计算机专业的学生可能听说过,由LISP派生出的方言,比较有代表性的有CL,Scheme,包括受到LISP语言影响的Haskell,Erlang等(Erlang由于分布式应用,前几年大热),可以这样说C和LISP代表了计算机语言的两个流派,过程式(也称为命令式)语言和函数式语言。
这两个流派的形成要从解决问题的思路说起,我们都知道现在的计算机体系是冯诺依曼结构(存储转发结构),冯式结构本身就受到图灵机的启发,所以图灵机非常适合操作这个结构,强调通过有限集合解决机器的问题;而另一个分支是兰帕德范式(Lambda),强调直接从解决数学问题入手;于是计算机语言王国诞生了基于图灵机的过程式语言包括后来发展成为面向对象语言,而基于Lambda范式诞生的就是函数式编程语言。我查到的资料说图灵机和拉帕德表达式可以相互推导,在逻辑上证明是一致的,所以他们都可以操作冯诺依曼结构的计算机体系。(具体证明过程没有看到,估计也很难看懂)
总体来说函数式编程语言是一种编程范式,它将电脑运算视为数学上的函数计算,并且避免使用程序状态以及易变对象。函数编程语言最重要的基础是λ演算(lambda calculus)。而且λ演算的函数可以接受函数当作输入(引数)和输出(传出值)。
其实过程式语言和函数式语言的优缺点必须放在一定场景下才能准确分出其优缺点,就主观支持者而言,估计吵100年也难分高下;在资深码农世界存在各种鄙视链,每种语言都有其铁粉,我有一个朋友在学习了Erlang语言后曾经大骂oop(面向对象)耽误他的技术生命,所以为了避免无谓的争吵,本文重点强调在区块链智能合约应用场景下函数式语言的优点。
可能有人要问函数式语言作为一个古老的编程范式,为什么以前很少听说,其实了解计算机的发展就知道,软件的发展一直受制于硬件的发展,过程式语言来自最原始的图灵机模型(读、写、跳转这样操作),而函数式语言来自 Lambda 函数(符号替换、规约等操作),过程式语言较函数式语言在性能上有先天优势,所以在硬件能力比较落后的70~80年代,过程式语言的优势明显所以,以C为代表的语言得到了充分的发展,同时也影响了后期面向对象语言的发展,大学基本上都开设过程式语言的课程,所以大多数人只知道过程式语言,解决问题思路也一直受过程式语言的影响。
但是随着多线程、分布式计算的发展,过程式语言复杂的上下文逻辑,线程安全不能得到很好的保证,并行计算开发难度直线上升,于是人们开始从头找回函数式编程语言,函数式语言变量只与值有关,与物理存储地址无关。变量与值环境一一对应,这一性质就消除了程序与机器结构的相关性,使得程序员在进行编程的时候无需考虑计算的操作行为、计算机的状态变化。只要按照有关语言的语法,用数学或逻辑的方法给出问题的描述和目标即可求解,每一行代码都可以是一个独立的函数,输入输出清晰,非常适合多线程和并行计算,同时函数式语言更符合人类的思维习惯,在高可靠性场景中,代码更容易阅读和查错,代码运行稳定(Erlang语言就是代表,最早是70年代爱立信开发的交换机语言),所以这些年人们开始重新研究和发展函数式语言,包括近几年流行的函数式编程风格。
函数式语言的优点
在函数式语言中,由于数据全部都是不可变的,所以没有并发编程的问题,是多线程安全的。可以有效降低程序运行中所产生的副作用,对于快速迭代的项目来说,函数式编程可以实现函数与函数之间的热切换而不用担心数据的问题,因为它是以函数作为最小单位的,只要函数与函数之间的关系正确即可保证结果的正确性。