类型系统综述(一)

原文作者:Luca Cardelli,Microsoft Research

翻译与调整:Koshiba

本文改编自 Luca Cardelli 的 《Type Systems》[1] 的前两章,并对内容和顺序做了调整。

Luca Cardelli 个人主页:http://lucacardelli.name/indexMe.html

《Type Systems》 2004 版:http://lucacardelli.name/Papers/TypeSystems.pdf

在对类型系统分门别类和比较它们的长短处之前,我们不妨仔细读读前人的研究,学究式地讨论与了解:

  • 什么是类型?类型化语言与非类型化语言。

  • 类型系统设立的目的,它可以保证什么?

  • 什么是执行错误;安全与行为良好的异同。

  • 需要多大程度的安全 —— 安全与性能的权衡。

  • 如何形式化地描述类型系统。

目录

# 总述 #

# 类型的基本概念 #

# 类型

# 类型化语言和非类型化语言

# 显式类型与隐式类型

# 执行错误、安全、行为良好 #

# 执行错误和安全

# 执行错误和行为良好

# 强(类型)检查

# 弱(类型)检查

# 对语言和类型系统的若干讨论 #

# 语言应该是安全的吗?

# 语言应该类型化吗?

## 程序执行的经济性

## 小规模开发的经济性

## 编译的经济性

## 大规模开发的经济性

## 安全领域的开发和维护的经济性

## 语言特性的经济性

# 类型系统的预期性质

# 类型系统是如何被形式化的 #

# 用以描述类型系统的语言 #

# 断言

# 类型规则

#类型的推导

# 类型良好和类型推断

# 类型正确

参考


总述 #

类型系统的根本目的是防止程序运行过程中出现执行错误,这个非正式的声明激发了对类型系统的研究。它的准确性首先取决于一个相当微妙的问题 —— 什么是执行错误。然而即使解决了这个问题,没有执行错误也是一个相当不简单的性质。我们必须证明所有可以在编程语言中表达的程序都没有执行错误,才能说该语言是类型安全的。(注:原文是 type soundness,译为类型健全;我们使用了更通俗的术语 type safety,即 “类型安全”。)事实证明,在进行相当多的仔细分析后,才可能避免对编程语言的类型健全性提出错误或令人尴尬的声明。而类型系统的分类、描述和研究也已经成为一门正式的学科。

类型系统的形式化需要精确的符号和定义,以及对形式化性质的详细证明(以使人们相信定义确实是妥当的)。有时,这门学科变得相当抽象;但是我们应该始终记住,实用性仍是这些抽象的基本动机:

  • 抽象是出于需要,并且通常可以与具体的直觉相联系;

  • 形式化,作为一门技术,即便不完整地使用也可以达成相当有用的效果。

了解类型系统的主要原则可以帮助语言设计者避免(明显和不明显的)陷阱,看到语言特性彼此之间的独立性或联系,以此使语言设计得更加规范。

如果发展得当,类型系统还可以作为一门工具,以判断语言定义中的(重要部分)是否已经足够明晰 —— 非正式的语言描述(如自然语言,译者注)往往不能足够清晰和详细地说明语言的类型结构,以保证其实现起来没有歧义 —— 同一语言的不同编译器实现了略有不同的类型系统,这是经常发生的情况。此外,许多语言的定义被发现是类型不安全的,即使程序被类型检查器判定为可以接受,也会导致程序崩溃。理想情况下,形式化类型系统应该是所有带类型的编程语言的定义的一部分。这样一来,就可以根据精确的规范来衡量类型检查算法。而且,如果可能与可行的话,整个语言都可以被证明是类型安全的。

接下来,我们会非形式化地介绍类型执行错误和其相关概念。我们讨论类型系统的预期性质和好处,并回顾类型系统如何被形式化。我们使用的术语并不是完全标准的;这是由于来自不同来源的标准术语的内在不一致性造成的。在提到运行时概念时,我们用动态检查来代替动态类型,并避免使用强类型这样常见但含糊的术语。

类型的基本概念 #

类型

在程序的执行过程中,一个程序变量可以承担一定的数值(数据)范围。这种范围的上限被称为该变量的类型。例如,一个布尔类型的变量 x 应该在程序的每次运行中只承担布尔值。如果 x 是布尔类型,那么布尔表达式 not(x) 在程序的每次运行中都有合理的意义;如果 x 承载了布尔以外的值,例如字符串,那么布尔表达式 not(x) 并无合理的意义。

类型化语言和非类型化语言

变量可以被赋予非平凡的(即非单一通用类型)类型的语言被称为类型化语言(原文为 typed languages 和 untyped languages,直译为 “类型化的语言” 和“非类型化的语言”,译者注)。

不限制变量范围的语言被称为非类型化语言:它们没有类型,或者说,有一个包含所有值的单一通用类型。在这些语言中,操作可以应用于不适当的参数:其结果可能是一个固定的错误值或一个异常等。

类型系统是类型化语言的组成部分,它记录变量的类型;一般来说,它也记录程序中所有表达式的类型。类型系统被用来确定程序是否表现良好。只有符合类型系统的程序才应该被认为是类型化语言的真正程序;不符合类型系统的程序应该被丢弃而从不运行。

显式类型与隐式类型

一种语言由于其类型系统的存在而被类型化,无论类型是否实际出现在程序的语法中。如果类型是语法的一部分,该语言就是显式类型的,否则就是隐式类型的。

没有哪种主流语言是纯粹的隐式类型,但是像 ML 和 Haskell 这样的语言支持编写省略类型信息的大型程序片段;这些语言的类型系统会自动为这些程序片段分配类型。

执行错误、安全、行为良好 #

典型的执行错误有非法指令错误或非法内存引用错误。然而,还有一些更微妙的执行错误,它们会导致数据损坏却不会被立刻感知。此外,有一些通常不会被类型系统预防的软件故障,例如除以 0 和对 NIL 解引用;也有些语言虽然缺乏类型系统,但软件故障却不会发生。因此,我们需要仔细定义我们的术语。

执行错误和安全

区分两类执行错误是很有用的:

  • 第一类是(在许多计算机架构上)会导致计算立即停止的 trapped [2] 错误,例如除以零和访问非法地址。(译者注:这里不太好翻译,因此保留了原单词。

  • 第二类是在发生时没有被注意到而在之后导致程序任意行为的 untrapped 错误,例如在没有运行时边界检查的情况下,访问超过数组末端的(错误)数据。

如果一个程序片段不会导致 untrapped 错误的发生,那么它就是安全的。所有程序片段都是安全的语言被称为安全语言。因此,安全语言排除了那些可能被忽视的最隐蔽的执行错误。非类型化语言可以通过执行运行时检查来实现安全。类型化语言可以通过静态检查来拒绝所有可能不安全的程序来实现安全(但静态检查通常不会特别精确,因此也会拒绝一些安全的程序)。类型化语言也可以使用运行时和静态检查的混合方式。

尽管安全性是程序的一个重要性质,但类型化语言很少只关注和排除 untrapped 错误,即类型化语言通常也致力于排除 trapped 错误。我们接下来讨论这些问题。

执行错误和行为良好

对于任何给定的语言,我们可以挑选执行错误的一个子集作为禁止的错误。(译者注:编译器必须能检查出的错误。)禁止的错误应该包括所有 untrapped 错误以及 trapped 错误的一个子集。

如果一个程序片段运行时不会发生任何禁止的错误,那么它就是行为良好的。通过简单推论可知,一个行为良好的程序片段总是安全的。

强(类型)检查

一个所有合法程序都有良好行为的语言被称为强(类型)检查的。

因此,对于一个给定的类型系统,以下情况在强检查语言中成立:

  • 没有 untrapped 错误。

  • 被禁止的 trapped 错误不会发生。

  • 其他 trapped 错误可能会发生;避免这些错误是程序员的责任。

类型化语言可以通过执行静态(即编译时)检查来强制保证行为良好(和安全)。这些语言是静态检查的,检查过程被称为类型检查,而执行这种检查的算法被称为类型检查器。一个通过类型检查器的程序被称为类型良好的;否则,它就是类型错误的 —— 但这可能意味着它就是行为不良的,也可能仅仅意味着类型检查器不能保证它是行为良好的。静态检查语言的例子有 ML、Java 和 Pascal(注意,Pascal 有一些不安全的特性)。

非类型化语言可以通过足够详细的运行时检查来排除所有禁止的错误,来强制保证行为良好(和安全)。例如,它们可以检查所有的数组边界和所有的除法操作,当禁止的错误发生时,产生可恢复的异常。这些语言的检查过程被称为动态检查;LISP 就是这种语言的一个例子。注意,这些语言仍然是强检查的,尽管它们既没有静态检查,也没有类型系统。

即使是静态检查的语言通常也需要在运行时进行测试以达到安全的目的。例如,一般来说,数组的边界必须在动态中进行测试。因此一种语言被静态检查的事实并不一定意味着可以完全盲目地执行。

一些语言利用其静态类型结构来进行复杂的动态测试。例如,Simula67 的 INSPECT,Modula-3 的 TYPECASE,以及 Java 的 instanceof 结构,都是对对象的运行时类型进行区分。这些语言仍然被认为是静态检查的(稍有不妥),部分原因是动态类型测试是在静态类型系统的基础上定义的。也就是说,对类型相等的动态测试与类型检查器在编译时用来确定类型相等的算法是兼容的。

也许安全性是一个更原始的、比行为良好更重要的性质,然而大多数类型系统的设计是为了确保更一般的行为良好性质,以及隐含的安全性。因此,类型系统的目标通常是通过区分类型良好和类型错误的程序来确保所有程序行为良好。

(类型)检查

在现实中ÿ

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值