浅谈编程语言的类型系统

浅谈编程语言的类型系统

类型系统(type system)是一门编程语言最核心也是最基础的部分。无论该语言基于何种编程范式,都必须在开天辟地之初首先对类型系统作出明确的定义。这是因为,编程语言虽然五花八门,千奇百怪,但是归根结底,编程语言最终的目标,本质上无非是回答两个问题:

  1. 如何表示信息;
  2. 如何处理信息。
无论是面向过程的编程语言、面向对象的编程语言、函数式编程语言、并行编程语言或者其他任何千奇百怪的编程语言,其根本性的终极目标,就是回答以上两个问题。各种编程语言之所以差异颇大,其实就是对这两个问题给出的答案不同导致的。
在如何表示信息这一问题上,编程语言通常需要定义一些“基本存储单元”,作为整个语言世界的基本构成要素。这种思想很类似于我们对物理世界的认识——宇宙虽然鬼斧神工,丰富多彩,但是在微观上,整个世界仅仅是由少数寥寥几种基本粒子构成的(物理细节不必深究,这里只是打个比方)。但是奇怪的是,基本粒子就只有几种,为何却能构成地球、水、人、树、风这些看似截然不同的东西呢?答案在于,基本粒子虽然不多,但是自然界确立了一套简单而精妙的组合规则,使得基本粒子能够以许多种不同的方式组合在一起,由于组合方式的不同(结构差异),组合规模的不同(数量差异),导致了最终宏观表现的不同。
与现实物理世界类似,一门编程语言就确立了一个独特的“世界”,这个世界可能丰富多彩,千奇百怪。但是就如我们现实世界一样,繁杂的外表之下,骨子里都是由一些“基本粒子”,按照一定的组合方式构成的。那么究竟有哪些基本粒子,又允许进行何种组合,对编程语言所确立的世界最终的宏观结果影响非常巨大。甚至可以说是根本性的。
有一定编程经验的程序员,往往对类型系统不太关心。他们更感兴趣的是语言的其他特性,例如并行计算能力,编程风格,类库等等。这些特性当然非常重要,就生产环境的应用来说,语言特性甚至是处于次要地位的。类库被许多程序员认为比语言本身更重要。然而,坚实的应用是以对语言深刻的理解为基础的,花费一些时间对语言的本质进行研究,会对深入理解语言背后的设计考虑有很大的帮助。也能让我们避免陷入语言的陷阱,或者陷入与别人的口水战之中。
回到对类型系统的考虑,那么究竟什么是类型系统呢?
一门语言定义了一套基本类型的“集合”,这个集合就作为一个整体被称为类型系统。这一称谓中,涉及到两个关键词——“类型”和“系统”。
什么是“类型”?
计算机存储是以二进制方式进行的,并以连续的八个二进制位为一个基本单元——“字节”。从这一点来看,计算机存储是通用的,存储人类的文字或者存储图像、声音或其他别的媒介都没有内在的本质差异。但是奇怪的是,在编程语言概念上,却总是会引入一系列的大相径庭的“基本类型”。例如,int和double,一个存储整数,一个存储浮点数。如果我们考虑一下,就会发现其实int和double本身并没有什么差别,都只不过是若干个字节构成的存储单元而已。那么对他们进行区分意义何在?其实就“存储”概念而言,我们用二进制方式,以字节为单位来实现信息的存储,已经给出了信息表示的“终极答案”了。但是完成存储,只是整个计算机系统功能的一部分。如果仅仅是把信息存储,而不进行计算,那么计算机就不叫计算机,改叫存储机了。可见,问题的实质在于,我们要存储,更要计算。
int和double都是几个字节构成的,但是其运算规则截然不同,差异巨大。同样的,string和int或double也不相同。我们在string上进行拼接、删减、搜索、替换。但是在int上进行加减乘除。这些计算需求和内部实现上的差异,迫使我们的语言层次上进行明显的区分。
上面举的类型,都是来自C家族语言中的概念。但是我们也知道,在一些语言中,不需要我们对类型进行显式的说明。但是不说明不代表不存在。只不过一个是程序员显式声明,一个是编译器(或解释器)自主推导;一个是把责任推给程序员,一个是把责任推给编译器作者。类型系统总是内在的存在的。永远没有被去除。
什么是“系统”?
坦白讲,这是一个非常模糊的概念。我们会说操作系统、消化系统、生态系统……各种各样的系统,然而对于系统本身是什么,在不同的科学领域有截然不同的定义。通常我们所说的系统中,存在一些基本要素(软件模块、细胞、物种等等),然后存在一定的相互作用关系(函数调用、细胞连接、捕食与被捕食等等),在此基础上实现一定的功能(完成金融计算、排解人体毒素、完成有机物的自然循环等等)。那么我们就把这些基本元素,以及其构成方式,统称为一个系统。
之所以说“系统”是个模糊的概念,原因在于,这一概念本身并非原子概念,一个系统,也可能再分解为一系列的子系统,例如操作系统就可以分为输入输出子系统,绘图子系统等等,人体内的消化系统也能够分解为一系列的子系统。而子系统又可在更小的级别进行分解。系统的划分是相对的,系统的构成也是相对的,因此其本身常常是模糊的。
这么说来,如果要追究系统一词的内涵,会很困难。但是在我们讨论的编程语言这一领域内,当提到“类型系统”时,系统其实就是指:
  • 一组基本类型构成的“基本类型集合”;
  • “基本类型集合”上定义的一系列组合、运算、转换方法。
这两点合起来,就成为了我们的“类型系统”。只要做到这两点,就已经非常强大了。这其中,“基本类型集合”是一个非常小的有限集合,也就寥寥几个元素,而“组合、运算、转换”等规则,也是一个较小的有限集合。但是通过选择不同的元素进行组合,这两个有限的集合之上,却衍生出了一个无限集合——“类型空间”。
理解这一点非常关键。因为这恰好符合了我们对自然界构成的认识——有限的若干种基本粒子,有限的若干种基本规则,结果却是无限可能性的巨大世界。
这一简单优雅而惊人的世界构成观贯穿了人类现实世界和计算机编程语言所定义的虚拟世界。或许语言的设计者也没有料想到,但是最终的结果确实是有限的设计导出了无限的可能性
所以,当认识到这一点之后。就再也不会轻视类型系统,再也不会把类型系统看得简单,自以为十分了解了。而类型系统设计上的细微差异,最终也会导致截 然不同的类型空间,导致对信息表达方式的巨大差异。那么还有什么理由不认真的研究这一基本要素的呢?还有什么理由让我们逃开这一许多程序员认为“简单”的主题呢?

阅读更多
换一批

没有更多推荐了,返回首页