第1章 JVM语言家族概览 《Kotin 编程思想·实战》
第1章 JVM语言家族概览
《Kotlin极简教程》正式上架:
点击这里 > 去京东商城购买阅读
点击这里 > 去天猫商城购买阅读
非常感谢您亲爱的读者,大家请多支持!!!有任何问题,欢迎随时与我交流~
天地和而万物生,阴阳接而变化起。《荀子·礼记》
1.1 编程语言简述
1.1.1 编程语言是什么
所谓编程语言只是一个抽象的规范,而编译器是这个规范的实现,它是在这个规范的严格定义下被实现的.
打个比方,这个语言规范,就像是一份制造汽车的图纸,他规定了汽车应该有什么,拥有什么功能,等等各个方面,而编译器就是一辆根据这张图纸制造出来的汽车,它实现了图纸的定义,这样你才能真正的使用这辆汽车。而我们用这门语言写源代码去解决一个问题的过程,就好比是你开着这辆车,去你想去的各个地方,享受着这辆车的驾驶的乐趣的过程。
这辆车本身设计的好坏,以及制造出来的质量如何,很大程度上影响了我们使用车的过程。类似的,这门语言本身设计的理念思想哲学,工程架构合理性,易用性等等,以及这个编译器实现的质量,很大程度上影响了我们使用这门语言的过程。
编程语言和编译器的关系,可以用面向对象编程思想里面的类和对象的关系来类比。他们谁也离不开谁,只有两部分共同合作,你才能使用这个语言.
1.1.2 怎样学习一门语言
学习一门语言大概会经历如下几步。
1.基本语法
学习任何东西,都是一个由表及里的过程。学习一门编程语言也一样。对于一门编程语言来说,“表” 就是基本词汇和语法。
对于基础语法的学习,我们可以看一些简短而又系统的教程。
2.编码实践
所谓“纸上得来终觉浅,绝知此事要躬行”是也。此处就不多说。
掌握基础,持续练习
每一门编程语言的学习内容都会涉及:
运行环境
数据类型(数字、字符串、数组、集合、映射字典等)
表达式
函数
流程控制
类、方法
等等,不同的语言还有一些不同的特性,这些内容并不复杂,尽快通过大量的练习击倒它们,然后再去深入了解面向对象编程OOP、函数式编程FP、并发、异常、文件IO、网络、标准库等内容,并辅以持续的练习,这些内容才能够让你真正进入编程领域并做出实际的软件。
学习一门新的语言的时候,要利用以前所学的语言的功底,但是也要保持开放的心态。
3.技近乎道
基础语法学习,能让你快速上手,应用实践。对技巧和坑的关注,一定程度上拓展了你的知识面。系统学习,一方面会进一步拓展你的知识面。另一方面,也有利于你语言知识结构的形成。
任何一门成熟语言,都有其特有的生态。这个生态包括: 框架,扩展包,解决方案,模式, 规范等。
在不断编码实践过程中,我们逐步熟练使用很多API库、框架,也不断踩坑填坑、看源代码、不断解决问题,不断加深对语言的理解,同时会看一些优秀的框架源代码。
如果还有精力,我还会去学习下语言更底层的东西。而不仅仅停留在应用层面。如Java中的集合类实现的算法与数据结构,如JVM是如何执行Java代码的。如Java的线程和操作系统线程的关系。以及一些操作系统方面的知识。
最后,达到游刃有余的境界。这一层级,基本可入武林高手之列了。
庖丁释刀对曰:“臣之所好者,道也,进乎技矣。始臣之解牛之时,所见无非牛者。三年之后,未尝见全牛也。方今之时,臣以神遇而不以目视,官知止而神欲行。依乎天理,批大郤,导大窾,因其固然,技经肯綮之未尝,而况大軱乎!
这里的“牛”,可以理解为我们所说的各种编程思想,编程范式,编程方法,编程技巧等等。最后,达到“运用之妙,存乎一心”之境也。
4.创造新世界
编程的本质就是创造世界。
达到这个境界的,基本都是世界顶尖大牛了。
编程语言发展史上的杰出人物:
约翰·冯·诺伊曼,操作系统概念的发起者。
肯·汤普逊,发明了Unix。
丹尼斯·里奇,发明了C。
约翰·巴科斯,发明了Fortran。
阿兰·库珀,开发了Visual Basic。
詹姆斯·高斯林,开发了Oak,该语言为Java的先驱。
安德斯·海尔斯伯格,开发了Turbo Pascal、Delphi,以及C#。
葛丽丝·霍普,开发了Flow-Matic,该语言对COBOL造成了影响。
肯尼斯·艾佛森,开发了APL,并与Roger Hui合作开发了J。
比尔·乔伊,发明了vi,BSD Unix的前期作者,以及SunOS的发起人,该操作系统后来改名为Solaris。
艾伦·凯,开创了面向对象编程语言,以及Smalltalk的发起人。
Brian Kernighan,与丹尼斯·里奇合著第一本C程序设计语言的书籍,同时也是AWK与AMPL程序设计语言的共同作者。
约翰·麦卡锡,发明了LISP。
比雅尼·斯特劳斯特鲁普,开发了C++。
尼克劳斯·维尔特,发明了Pascal与Modula。
拉里·沃尔,创造了Perl与Perl 6。
吉多·范罗苏姆,创造了Python。
......
正是这些各个编程领域的引领者们,才使得我们这个世界更加美好。
1.2 编程简史
1940之前

1801,Joseph Marie Jacquard用打孔卡为一台织布机编写指令,在提花织布机(或称甲卡提花织布机,Jacquard loom)上,运用打孔卡上的坑洞来代表缝纫织布机的手臂动作,以便自动化产生装饰的图案。Jacquard织布机是第一台可进行程序控制的织布机。用打孔卡进行编程的概念,直到电子计算机被发明出来之后仍然被广泛运用。
1842,爱达·勒芙蕾丝(Ada lovelace)在1842年至1843年间花费了九个月,将意大利数学家Luigi Menabrea关于查尔斯·巴贝奇新发表机器分析机的回忆录翻译完成。分析机由于其设计思想过于先进,在当时根本没有 被制造出来。(Babbage的分析机一般被认为是现代电子通用计算机的先驱)。她于那篇文章后面附加了一个用分析机计算伯努利数方法的细节,被认为是世界上第一个电脑程序。 “她的努力只遇到了一点点小小的麻烦,那就是:实际上并没有任何计算机能够用来运行她的程序。后来的企业架构师们重新吸收了她的这个技能,用来学习如何更好地使用UML进行编程。”[8]
1890,霍列瑞斯(Herman Hollerith)在观察列车长对乘客票根在特定位置打洞的方式后,意识到他可以把信息编码记载到打孔卡上,随后根据这项发现使用打孔卡来编码并纪录1890年的人口统计数据(这种语言是种编码)。
1936, Alan Turing发明了世间一切程序语言的最终形态,但很快他就被英国军情六处“请”去当007了。与通用图灵机(Universal Turing machine)等价的语言被称为图灵完备的(Turing completeness),它定义了“什么样的语言可以被称作是程序语言”。
1936 , Alonzo Church同时也发明了世间一切程序语言的最终形态,甚至做得更好。他发明的λ演算是当今函数式编程(FP)的鼻祖,对函数式编程有巨大的影响,特别是Lisp 语言。Church是Turing在Princeton的博士生导师,他在λ演算方面的工作先于Turing指出了不存在一个对可判定性问题的通用解法,这后来证明和Turing针对停机问题提出的图灵机模型是等价的。即著名的“Church-Turing”论题。
1940年代
最早被确认的使用电的计算机诞生在1940年代。
程序员在有限的速度及存储器容量限制之下,撰写汇编程序。用汇编语言的这种撰写方式需要花费大量的脑力而且很容易出错。
康拉德·楚泽于1948年发表了他所设计的Plankalkül编程语言的论文。但是在他有生之年却未能将该语言实现。(关于康拉德·楚泽的故事,可参考本书:附录1)
在这段期间被开发出来的重要语言包括有:
1943 - Plankalkül (Konrad Zuse)
1943 - ENIAC coding system
1949 - C-10
1950与1960年代
在这段期间被开发出来的重要语言有:
1951 - Regional Assembly Language
1952 - Autocode
1954 - FORTRAN
1954 - IPL (LISP的先驱)
1955 - FLOW-MATIC (COBOL的先驱)
1957 - COMTRAN (COBOL的先驱)
1958 - LISP
1958 - ALGOL 58
1959 - FACT (COBOL的先驱)
1959 - COBOL
1962 - APL
1962 - Simula
1962 - SNOBOL
1963 - CPL (C的先驱)
1964 - BASIC
1964 - PL/I
1967 - BCPL (C的先驱)
其中有三个现代编程语言于1950年代被设计出来,这三者所派生的语言直到今日仍旧广泛地被采用:
Fortran ,1954
名称取自"FORmula TRANslator"(公式翻译器),约翰·贝克斯(John Backus)针对汇编语言的缺点而研究开发的语言。
LISP,1958
名称取自"LISt Processor"(枚举处理器),约翰·麦卡锡(John McCarthy)在1958年基于λ演算所创造,采用抽象数据列表与递归作符号演算来衍生人工智能。LISP为函数式程序设计语言,所有运算都能以函数作用于参数的方式来实现。LISP核心的操作符只有7个:quote、atom、eq、car、cdr、cons、cond。前三者quote、atom、eq用于符号的推断;car、cdr、cons操纵表格;cond负责分支判断。这种简洁定义,非常接近图灵机原型的纯函数式语言,是现代语言完全无法比拟的。
ALGOL 60,1960
名称取自"ALGOrithmic Language"(算法语言)。ALGOL 60是程序设计语言由技艺转向科学的重要标志,其特点是局部性、动态性、递归性和严谨性,发明于1960年。ALGOL 60强化了当时许多关于计算的想法,并提出了两个语言上的创新功能:
(1)嵌套区块结构(Nested block structure):可以将有意义的代码片段组群成一个区块(block),而非转成分散且特定命名的程序。
(2)词汇范围(lexical scoping):区块可以有区块外部无法通过名称访问,属于区块本身的变量、程序以及函数。
另一个创新则是关于语言的描述方式:
一种名为巴科斯-诺尔范式 (BNF)的数学化精确符号被用于描述语言的语法。之后的编程语言几乎全部都采用类似BNF的方式来描述程序语法中上下文无关的部分。
Pascal、Ada、Simula、C等都借鉴了ALGOL。
COBOL,1961
名称取自"COmmon Business Oriented Language"(通用商业导向语言),由格雷斯·霍波(G.Hopper)所开发。COBOL语言以代码极其冗长和通篇大写字母的书写风格而闻名。据称用COBOL书写的程序超过了2000亿行。另有调查发现世界上目前使用的商业应用软件之中的百分之七十是用COBOL代码编写的。
BASIC,1964
BASIC (初学者通用符号指令代码,Beginners' All-purpose Symbolic Instruction Code),匈牙利人约翰·凯梅尼(John G. Kemeny)与数学教师托马斯·卡茨(Thomas E. Kurtz)认为像FORTRAN那样的语言都是为专业人员设计,没有办法普及。于是,他们在简化FORTRAN的基础上由共同研制出来的。1964年BASIC语言正式发布。第一个BASIC程序在1964年5月1日早上4时,由BASIC编译程序进行编译后成功运行 。1975年,比尔·盖茨把它移植到PC上。
1967-1978:确立基础范式
在1960年代以及1970年代中,结构化程序设计的优点也带来许多的争议,特别是在程序开发的过程中完全不使用GOTO。
在这段期间被开发出来的重要语言有:
1968 - Logo
1970 - Pascal
1970 - Forth
1972 - C语言
1972 - Smalltalk
1972 - Prolog
1973 - ML
1975 - Scheme
1978 - SQL (起先只是一种查询语言,扩充之后也具备了程序结构)
1960年代晚期至1970年代晚期的期间中,编程语言的发展也有了重大的成果。大多数现在所使用的主要语言范式都是在这段期间中发明的。
Simula,1967
第一个面向对象编程语言。由挪威科学家Ole-Johan Dahl和Kristen Nygaard,以Algol 60超集的方式设计开发。
Pascal,1970
Niklaus Wirth(就是那位说:“算法+数据结构=程序” 的人)创造了Pascal,一个过程式的语言。Pascal语言语法严谨,层次分明,程序易写,具有很强的可读性,是第一个结构化的编程语言。Pascal的名称是为了纪念十七世纪法国著名哲学家和数学家Blaise Pascal。
C,1972
源自Ken Thompson发明的B语言,而 B语言则源自BCPL语言。1967年,剑桥大学的Martin Richards对CPL语言进行了简化,于是产生了BCPL(Basic Combined Programming Language)语言。1970年,美国贝尔实验室的 Ken Thompson,以BCPL语言为基础,设计出很简单且很接近硬件的B语言(取BCPL的首字母)。并且他用B语言写了第一个UNIX操作系统。
1971年,Dennis M.Ritchie伙同Thompson一起,合作开发UNIX。1972年, D.M.Ritchie 在B语言的基础上设计出C语言。Thompson和Ritchie就用C完全重写了UNIX。在开发中,他们还考虑把UNIX移植到其他类型的计算机上使用。C语言强大的移植性(Portability)在此显现。机器语言和汇编语言都不具有移植性,为x86开发的程序,不能在Alpha,SPARC和ARM等机器上运行。而C语言程序则可以使用在任意架构的处理器上,只要那种架构的处理器具有对应的C语言编译器和库,然后将C源代码编译、连接成目标二进制文件之后即可运行。
未来的JVM的“虚拟机”的思想,在某种程度上正是源自这里,通过对不同平台上JVM的实现,向上封装一层,从而使得基于JVM的编程语言可以更大限度的实现了跨平台(当然,对应需要实现各个平台上(比如说Windows,Linux,Mac OS)的JDK)。
Smalltalk,1975
由Alan Kay,Dan Ingalls,Ted Kaehler,Adele Goldberg等于70年代初在Xerox PARC开发的面向对象编程语言。
Alan Kay 总结了 Smalltalk 的五大基本特征。这是第一种成功的面向对象程序设计语言,也是Java 的基础 语言。通过这些特征,我们可理解“纯粹”的面向对象程序设计方法是什么样的:
(1) 所有东西都是对象。可将对象想象成一种新型变量;它保存着数据,但可要求它对自身进行操作。理论 上讲,可从要解决的问题身上提出所有概念性的组件,然后在程序中将其表达为一个对象。
(2) 程序是一大堆对象的组合;通过消息传递,各对象知道自己该做些什么。为了向对象发出请求,需向那 27
个对象“发送一条消息”。更具体地讲,可将消息想象为一个调用请求,它调用的是从属于目标对象的一个 子例程或函数。
(3) 每个对象都有自己的存储空间,可容纳其他对象。或者说,通过封装现有对象,可制作出新型对象。所 以,尽管对象的概念非常简单,但在程序中却可达到任意高的复杂程度。
(4) 每个对象都有一种类型。根据语法,每个对象都是某个“类”的一个“实例”。其中,“类”(Class) 是“类型”(Type)的同义词。一个类最重要的特征就是“能将什么消息发给它?”。
(5) 同一类所有对象都能接收相同的消息。[10]
Smalltalk对其它众多的程序设计语言的产生起到了极大的推动作用,例如:Objective-C,Actor, Java 和Ruby等。90年代的许多软件开发思想得利于Smalltalk,例如Design Patterns, Extreme Programming(XP)和Refactoring等。
Prolog,1972
Prolog语言最早由Aix-Marseille大学的Alain Colmerauer与Phillipe Roussel、Kowalski等人于60年代末研究开发。它建立在逻辑学的理论基础之上, 最初被运用于自然语言等研究领域。现已广泛的应用在人工智能的研究中,可以用来建造专家系统、自然语言理解、智能知识库等。
ML,1973
ML(Meta Language)是Robin Milner主管LCF项目时(1970),作为LCF项目的元语言(Meta Language)而设计的,这也是其名字的来历。LCF项目是受Dana Scott给出的一组逻辑原则启发而设立的,致力于开发一种“可计算函数逻辑”(Logic of Computable Functions)。目标是构造一个方便实用的系统,来自动的或者半自动的证明函数程序中一些有趣的性质。今天,大多数著名的推理系统都是用ML写的。目前ML有两个发展分支:Standard ML和Caml。
ML使用了Hindley-Milner类型推论算法来推测大多数值的类型,而不需要四处使用注解。ML一般被归为非纯函数式编程语言,因为它允许副作用和指令式编程。这一点和纯函数式编程语言例如Haskell很不一样。ML特性有惰性求值的求值策略,一阶类型函数, 带有垃圾收集的自动内存管理, 参数多态,静态数据类型,类型推断,代数数据类型,模式匹配和异常处理等。ML中的思想影响了众多的语言,例如Haskell,Cyclone和Nemerle。
这些语言都各自演展出自己的家族分支,现今多数现代编程语言的祖先都可以追溯他们其中至少一个以上。
1980年代:增强、模块、性能
1980年代的编程语言与之前相较显得更为强大。C++合并了面向对象以及系统程序设计。美国政府标准化一种名为Ada的系统编程语言并提供给国防承包商使用。日本以及其他地方运用了大量的资金对采用逻辑编程语言结构的第五代语言进行研究。函数编程语言社区则把焦点转移到标准化ML及Lisp身上。这些活动都不是在开发新的范式,而是在将上个世代发明的构想进一步发扬光大。
然而,在语言设计上有个重大的新趋势,就是研究运用模块或大型组织化的程序单元来进行大型系统的开发。Modula、Ada,以及ML都在1980年代发展出值得注意的模块化系统。模块化系统常拘泥于采用泛型程序设计结构:泛型存在(generics being)、本质(essence),参数化模块(parameterized modules)。(参阅多态)
尽管没有出现新的主要编程语言范式,许多研究人员仍就扩充之前语言的构想并将它们运用到新的内容上。举例来说,Argus以及Emerald系统的语言配合面向对象语言运用到分布式系统上。
1980年代的编程语言实现情况也有所进展。计算机系统结构中RISC的进展假定硬件应当为编译器设计,而非身为人类的汇编语言程序员。借由中央处理器速度增快的帮助,编译技术也越来越积极,RISC的进展对高级语言编译技术带来不小的关注。
语言技术持续这些发展并迈入了1990年代。
在这段期间被开发出来的重要语言包括有:
1980 - Ada
1983 - C++ (加上类的C)
1984 - Common Lisp
1985 - Eiffel
1986 - Erlang
1987 - Perl
1988 - Tcl
1989 - FL (Backus)
C++,1983
Bjarne Stroustrup,他使用过Simula和ALGOL,接触过C。他对Simula的类体系感受颇深,对ALGOL的结构也很有研究,深知运行效率的意义。既要编程简单、正确可靠,又要运行高效、可移植。于是Bjarne Stroustrup以C为背景,以Simula思想为基础,把他所听说过的一切都试图嫁接到C上,创造出了C++。它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。C++擅长面向对象程序设计的同时,还可以进行基于过程的程序设计,因而C++就适应的问题规模而论,大小由之。
1990年代:互联网时代
1990年代未见到有什么重大的创新,大多都是以前构想的重组或变化。这段期间主要在推动的哲学是提升程序员的生产力。
许多"快速应用程序开发" (RAD) 语言也应运而生,这些语言大多都有相应的集成开发环境、垃圾回收等机制,且大多是先前语言的派生语言。这类型的语言也大多是面向对象的编程语言,包含有Object Pascal、Visual Basic,Java以及C#。
Java,1995
1995年,互联网的蓬勃发展给了Oak(Java之前的名字)机会。Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。
我们将在下一章中介绍Java编程简史。另外,关于上面提到的“提升程序员的生产力”的哲学理念,本书介绍的SpringBoot框架,就是为了推动程序员的生产力而设计开发的。不管在编程语言设计领域,还是在编程框架的开发领域,很大一部分的目的,就是为了这一点。
在这段期间被开发出来的重要语言包括有:
1990 - Haskell
1991 - Python
1991 - Visual Basic
1993 - Ruby
1993 - Lua
1994 - CLOS (part of ANSI Common Lisp)
1995 - Java
1995 - Delphi (Object Pascal)
1995 - JavaScript
1995 - PHP
1997 - REBOL
1999 - D
当今的趋势
编程语言持续在学术及企业两个层面中发展进化,目前的一些趋势包含有:
-
在语言中增加安全性与可靠性验证机制:额外的堆栈检查、信息流(information flow)控制,以及静态线程安全。
-
提供模块化的替代机制:混入(mixin)、委派(delegates),以及观点导向。
-
组件导向(component-oriented)软件开发。
-
元编程、反射或是访问抽象语法树(Abstract syntax tree)
-
更重视分布式及移动式的应用。
-
与数据库的集成,包含XML及关系数据库。
-
支持使用Unicode编写程序,所以源代码不会受到ASCII字符集的限制,而可以使用像是非拉丁语系的脚本或延伸标点符号。
-
图形用户界面所使用的XML(XUL、XAML)。
等等。
在这段期间被开发出来的重要语言包括有:
2001 - C#
2001 - Visual Basic .NET
2002 - F#
2003 - Scala
2003 - Factor
2006 - Windows PowerShell
2007 - Clojure
2009 - Go
2014 - Swift (编程语言)
1.3 怎样设计一门编程语言?
编程语言设计我们需要一个抽象的逻辑规范X,这个规范规定了这门语言的基本词汇,语法,运算符,表达式,数据类型,等等。设计的语言必须满足图灵完备性,才能够表达任何一个可计算的问题。
然后,我们在这个规范下实现一个编译器Compiler,可以翻译在这个规范下写出来的语言文本(即源代码)。翻译成的目标语言,就是操作系统可执行的机器码(遵循其CPU指令集规范)或者是虚拟机VM可执行的字节码(遵循VM规范的指令集)。
现代很多语言的编译器是用自己写成的——只要你有一个其他语言写的编译器来让这个自解释循环启动起来。
不管是exe可执行文件还是Linux,Mac OS下的程序,都是一些二进制代码,我们称之为机器语言。这些代码的执行和操作系统以及CPU硬件都有关。
大部分情况下,编译器是一种将高级语言翻译成机器语言的程序。这个程序本身也是一些机器语言的代码。机器代码是可以直接运行的。
无论是高级语言、汇编语言还是机器语言,实际上都是等价的,唯一有区别的是,越高级的语言,我们人类写起来越容易,所以有那么多的高级语言代码不断被设计发明出来。说不定哪一天,人类可以发明出可以直接写程序的“程序”——机器程序员。
1.4 程序执行的三种方式
1.4.1 编译执行
1.4.2 解释执行
1.4.3 虚拟机执行
1.5 一切皆是映射
计算机领域中的所有问题,都可以通过向上一层进行抽象封装来解决.这里的封装的本质概念,其实就是”映射“。
就好比通过的电子电路中的电平进行01逻辑映射,于是有了布尔代数,数字逻辑电路系统;
对01逻辑的进一步封装抽象成CPU指令集映射,诞生了汇编语言;
通过汇编语言的向上抽象一层编译解释器,于是有了pascal,fortran,C语言;
再对核心函数api进行封装形成开发包(Development Kit), 于是有了Java,C++ 。这一切的过程都是向上层抽象映射的过程。
从面向过程到面向对象,再到设计模式,架构设计,面向服务,各种软件理论五花八门,但万变不离其宗——
你要解决一个怎样的问题?
你对这个世界的本质认知是怎样的?
你要解决领域的问题是什么?
等等。
1.5.1 二进制的01世界与现实的阴阳世界
编程的本质跟大自然创造万物的本质是一样的。
二进制的“0”和“1”通过计算机里能够创造出一个虚拟的、纷繁的世界。自然界中的阴阳形成了现实世界的万事万物。
所以自然世界的“阴”、“阳”作为基础,切实地造就了复杂的现实世界,计算机的“0”和“1”形象地模拟现实世界的一切现象,易学中的“卦”和“阴阳爻”抽象地揭示了自然界存在的事件和其变化规律。
另外,阴阳就是在同一个属概念“对立统一(全集U)”下的两个种概念“阴(集X)和阳(集Y)”之间的一种不相容关系。阴阳的内涵互相否定,一个概念“阴集”肯定对象阴的属性,而否定“阳”的属性;另一个概念“阳集”则以否定阴概念所肯定的属性而肯定“阳”的属性;
阴阳的外延互相排斥
X∩Y=0
而又互补
X∪Y=U=1
1-Y=X
其总和等于它们最邻近的属概念(对立统一整体)的外延,即两个种概念阴阳外延的和或并
X+Y=X∪Y=U
OK,这就是我们熟知的,数理逻辑里面的所谓的bool代数了。
布尔代数起源于数学领域,是一个用于集合运算和逻辑运算的公式:〈B,∨,∧,¬ 〉。其中B为一个非空集合,∨,∧为定义在B上的两个二元运算,¬为定义在B上的一个一元运算。
通过布尔代数进行集合运算可以获取到不同集合之间的交集、并集或补集,进行逻辑运算可以对不同集合进行与、或、非。
1.6 向上抽象封装一层
一切皆是映射。
人的生命只有一次。生命太短暂,所以不要去做一些重复无聊的事情。能交给计算机做的,就尽量交给计算机去做。此乃编程之滥觞之地。
未来人工智能将取代大部分的重复手工劳动。将大大解放人类的劳动力,从而使得人类能够花更多的时间和精力,去创造去创新。而人工智能的本质,就是对人类智能的抽象建模。我们人类写的操作系统、浏览器、办公软件、画图设计工具、3D建模软件、电商系统、金融平台、社交APP,不就是另一种层次上的人工智能吗?这些东西,背后都是01的映射。当然,01背后是物理层次的,量子微观的世界了。
纵览整个计算机的发展史,最重要的思想非“抽象”莫属。
一层层的抽象封装了实现的细节,计算机开疆扩土,南征北战,发展到了今天蔚为壮观的互联网,云计算,大数据,机器智能的时代。
同时,也使得程序员写代码,从最初的拿着符号表在纸袋上打孔,到使用近似自然语言的高级编程语言来编程(当然背后少不了编译器、解释器,还有的是先通过虚拟机中间字节码这一层,再通过解释器映射到机器码,最后在硬件上作高低电平的超高频率的舞蹈),以及当今各种库API、框架、集成开发工具集,智能化的编码提示,代码生成等等技术,使得我们现在程序员,能更多的去关注问题本身以及逻辑的实现。
从只有少数技术人会用的命令行的操作系统unix、dos,到人性化的GUI图形界面操作系统,以及移动互联网时代的智能设备,计算机越来越融入到人类生活的方方面面。
正如解决数学问题通常我们会谈“思想”,诸如反证法、化繁为简等,解决计算机问题也有很多非常出色的思想。思想之所以称为思想,是因为“思想”有拓展性与引导性,可以解决一系列问题。
解决问题的复杂程度直接取决于抽象的种类及质量。过将结构、性质不同的底层实现进行封装,向上提供统一的API接口,让使用者觉得就是在使用一个统一的资源,或者让使用者觉得自己在使用一个本来底层不直接提供、“虚拟”出来的资源。
计算机中的所有问题 , 都可以通过向上抽象封装一层来解决。
1.7 JVM平台思想
Java虚拟机对各个平台而言,实质上是各个平台上的一个可执行程序。例如在windows平台下,java虚拟机对于windows而言,就是一个java.exe进程而已。

我们经常说的Java语言是平台无关的,跨平台的。其实这是针对从Java源代码到JVM字节码这一层是平台无关的(这一层的javac是Java代码写的,依然是跨平台)。
但是,真正到了把JVM字节码通过解释器映射到不同平台(操作系统,CPU硬件架构)上,JVM就必须针对各个平台实现一套解释器。只是这一层通过抽象封装,对我们程序员而言已经完全透明,无需做相关的工作而已。
在解释器层,作为JVM的设计开发者们(他们用的是C/C++),那就享受不到类似Java、Scala这样基于JVM跨平台的语言的特性了。
1.7.1 Java源代码编译执行过程
Java代码编译是由Java源码编译器来完成,流程图如下所示:

用哪种 JVM 语言?
使用哪种语言,完全依赖程序员的性情了。但是在项目,工作中“应该使用”哪种语言,往往会有诸多限制。
RebelLabs《Java工具和技术概览2014》[4]的报告上“要去学习的下一个JVM语言”:

RebelLabs《Java工具和技术概览2016》[4]的报告上的“你最常使用的JVM上的语言”:

丰富多彩的JVM生态
一个完整的语言有:
前端、优化、后端、runtime、库
JVM生态体系,把后面四个都给包办了。
jvm(Java虚拟机),是用C写的,跟操作系统打交道C/C++目前看来,是好的选择。虚拟机就是java与操作系统的中间层。
库/API就基本是java自身封装实现。
从最初的Jython和JRuby,到Scala,Clojure都是在JVM上实现的语言。为什么它们选择JVM?
跨平台
你的语言编译器后端只需要输出 JVM 字节码就可以。跨平台需要极大的工作量(这个轮子,造起来有点耗时耗力)
JIT (Just-In-Time 即时编译)性能
JIT 可以在运行中记录程序运行的特征,并在其基础上做大量的优化(Java 企业级应用的优秀性能很大程度上是由此而来)。 JIT 自从 HotSpot JVM 随 Java 1.2 发布以来,JVM JIT 的性能不断提高,是无可争议的成功产品。把 JVM 作为目标平台意味着大量的性能优化工作可以「外包」给 JVM 来做,大大缩减了 Guest 语言的开发预算。
JVM 作为一个成熟的高层运行环境,为 Guest 语言提供了很多运行时所需要的服务,比如内存管理(有业界领先的垃圾回收等),很大程度上避免了额外的独立开发。
社区庞大且成熟

JVM 有多个独立实现,也有若干厂商会持续推进,资料完备,社区巨大。
Java 社区有大量成熟的库,一般来说,运行在 JVM 上的其它语言都会设计一个专用的「桥」来帮助直接使用 Java 的库。
Java 有成熟的开发工具和环境。
题外话
另外一个趋势是把 Javascript 成为新的目标平台。很多主流语言都已经出现了编译器可以翻译成 Javascript,这也是得益于近年来 Javascript 虚拟机性能的显著提升。
List-of-languages-that-compile-to-JS:
https://github.com/jashkenas/coffeescript/wiki/List-of-languages-that-compile-to-JS
下一代普遍可接受语言(next mass-appeal language)
下一代普遍可接受语言(next mass-appeal language)中,人的因素应该起到重要作用。
- 新的程序设计语言中的代码片段应该具备一个典型程序员所希望的适度复杂性。程序员会去期望在每天的工作中使用的语言。
- 中级程序员认可。所谓中级程序员是指那些普遍对博客、微博或者新语言不感兴趣的人。
- 程序员可以不用别人的帮助或者接受培训,就能对新的程序设计语言中的代码片段的功能进行合理的准确的推测。
NBJL可以走多远就目前来看是难以下定论的,但是我相信这是一个比较实际的问题。我们所需要的新的程序设计语言能够不需要大规模的培训,程序员们可以快速上手。
在其功能方面,注诸如如下条目:
- 类C的语法(很好用也很熟悉)
- 静态类型(动态类型过于松散并且性能有限)
- 遵循面向对象程序设计(Object Oriented Programming,OOP)思想,并且包括函数式语言的元素(纯函数式言非主流编程语言)
- 易于反射获得(从而避免静态类型限制)
- 属性(getter和setter实在是太让人讨厌了)
- 闭包
- Null判断(提供一个判断变量能否为null的方式)
- 并发(好过原始线程和共享可变状态(shared mutable state))
- 模块化(需要考虑更大的单元)
- 工具(希望新语言能够对于工具开发有所帮助)
- 可扩展性(语言的设计具备很好的可扩展性,以支持其上的二次开发,而不需要去修改语言本身的设计)
...
当然还有其他一些可以讨论的主题-语言设计其实堪比艺术品设计,有太多角度可以观察了。
参考资料
1.https://www.tiobe.com/tiobe-index/
2.https://blogs.oracle.com/thejavatutorials/entry/jdk_8_is_released
3.https://en.wikipedia.org/wiki/List_of_JVM_languages
4.https://zeroturnaround.com/rebellabs/java-tools-and-technologies-landscape-2016/
5.http://www.oschina.net/translate/the-adventurous-developers-guide-to-jvm-languages
6.http://try.kotlinlang.org/#/Examples/Callable%20references/Composition%20of%20functions/Composition%20of%20functions.kt
7.http://www.jianshu.com/p/ece917620dfd