从上图中你会有如下几点感受:
第一个感受:阿布对 Java 一点兴趣也没有。
第二个感受:由于讨厌 Java ,阿布不想用 Java 的对象表示形式,于是就借鉴了 Self 语言,使用基于原型的继承机制。埋下了前几年前端界用原型进行面对对象编程的种子。
第三个感受:阿布借鉴了 Scheme 语言,将函数提升到一等公民的地位,让 JS 拥有了函数式编程的能力。埋下了 JS 可以进行函数式编程的种子。
第四个感受:JS 是既可以函数式编程,也可以面对对象编程。
3、我个人的感受我在回顾程序设计语言的发展史和一些故事后,我并不认为 JavaScript 是一个烂语言,相反正是这种中庸之道,才使得 JavaScript 能够流行到现在。
十二、总结通过对计算机语言的发展史和关键人物的简洁介绍,我们可以从高层面去体会到函数式编程在计算机语言发展史中的潜力和影响力。
不过,通过背景和人物的介绍,对函数式编程的理解还是有限的。下面我将通过提问的方式来阐述函数式编程的来龙去脉。
函数式编程的 10 问下面将通过 10 个问题的解答,来阐述函数式编程的理论支撑、函数式编程的诞生背景、函数式编程的核心理论以及推导等知识。
一、为什么会有函数式语言?函数式语言是如何产生的?它存在的意义是什么?函数式语言的存在,是为了实现运算系统的本质——运算。
1、形式化运算系统的研究
计算机未问世之前,四位大佬 阿兰·图灵、约翰 ·冯·诺依曼 、库尔特 ·哥德尔 和阿隆左 ·丘奇。展开了对形式化的运算系统的研究。
通过形式系统来证明一个命题:可以用简单的数学法则表达现实系统。
2、图灵机和冯·诺依曼结构体系的缺陷从上文的图片和分析可知,图灵机和冯诺依曼体系的计算机系统都依赖存储(内存)进行运算。
换句话说就是:通过修改内存来反映运算的结果。并不是真正意义上的运算。
修改内存并不是我们想要的,我们想要的仅仅是运算。从目的性的角度看,修改内存可以说是运算系统中的副作用。或者说,是表现运算结果的一种手段。
这一切,图灵的博导邱奇看在眼里,他看到了问题的本质。为了实现运算系统的本质——运算,即不修改内存,直接通过运算拿到结果。
他提出了 lambda 演算的形式系统,一种更接近于运算才是本质的理论。
3、函数式语言和命令式语言的隔阂从语言学分类来说:是两种不同类型的计算范型。
从硬件系统来说:它们依赖于各自不同的计算机系统(也就是硬件)。为什么依赖不同的硬件,是因为如果用冯诺依曼结构的计算机,就意味着要靠修改内存来实现运算。但是,这和 lambda 演算系统是相矛盾的。
因为基于 lambda 演算系统实现的函数式语言,是不需要寄存器的,也不存在需要使用寄存器去存储变量的状态。它只注重运算,运算结束,结果就会出来。
最大的隔阂就是依赖各自不同的计算机系统 。
4、计算机硬件的限制目前为止,在技术上做不到基于 A 范型的计算机系统,同时支持 B 范型。也就是说,不能指望在 X86 指令集中出现适用于 lambda 演算 的指令、逻辑或者物理设计。
你可能会疑问,既然硬件不支持,那我们为什么还能进行函数式编程?
其实现实中,大多数人都是用的冯诺依曼体系的命令式语言。所以为了获得特别的计算能力和编程特性。语言就在逻辑层虚拟一个环境,也因为这样,诞生了 JS 这样的多范型语言,以及 PY 这种脚本语言。
究其根源,是因为,冯·诺依曼体系的计算机系统是基于存储与指令系统的,并不是基于运算的。
5、黑暗中的曙光在当时硬件设备条件的限制下,邱奇提出的 lambda 演算,在很长时间内,都没有被程序设计语言所实现。
直到冯诺依曼等人完成了 EDVAC 的十年之后。一位 MIT 的教授 John McCarthy 对邱奇的工作产生了兴趣。在 1958 年,他公开了表处理语言 LISP 。这个 LISP 语言就是对邱奇的 lambda 演算的实现。
自此,世界上第一个函数式语言诞生了。
LISP 就是函数式语言的鼻祖,完成了 lamda 演算的实现,实现了 运算才是本质的运算系统。