CLU

CLU是一门编程语言，由芭芭拉·利斯科夫和她的学生在1974年到1975年于麻省理工学院（MIT）创造。虽然它没有被广泛使用，但它引入了抽象数据类型，和许多现在广泛使用的特性，而被视为面向对象编程发展的重要一步。

主要贡献还包括：传共享调用、迭代器、多值返回（并行赋值形式）、参数化类型和可变类型。值得注意的是它使用了具有构造器和方法的类，但没有继承。

## 聚类

CLU的语法基于了ALGOL，这是当时多数新语言设计的起点。关键增补是“聚类”（cluster）概念，它是CLU的类型扩展系统和语言名字的根源（CLUster）。聚类一般对应于面向对象语言中“类”（class）的概念。例如，下面是CLU用来实现复数的语法：

```
complex_number = <span style="color:green;font-weight: bold;">cluster</span> <span style="color:green;font-weight: bold;">is</span> add, subtract, multiply, ...
    rep = <span style="color:green;font-weight: bold;">record</span> [ real_part: <span style="color:brown;">real</span>, imag_part: <span style="color:brown;">real</span> ]
    add = <span style="color:green;font-weight: bold;">proc</span> ... <span style="color:green;font-weight: bold;">end</span> add;
    subtract = <span style="color:green;font-weight: bold;">proc</span> ... <span style="color:green;font-weight: bold;">end</span> subtract;
    multiply = <span style="color:green;font-weight: bold;">proc</span> ... <span style="color:green;font-weight: bold;">end</span> multiply;
    ...
<span style="color:green;font-weight: bold;">end</span> complex_number;
```

聚类是一个模块，它封装了除了那些在`is`子句中显式命名的成员之外的所有成员。这些成员对应于现在面向对象语言中一个类的公开成员。聚类还定义了可以在聚类之外引用名字的一个类型（在这个案例中是`complex_number`），但是它的表示类型（这里的`rep`）对于外部客户是隐藏的。

聚类名字是全局的，不提供名字空间机制来组织聚类，也不允许它们在其他聚类内部被“局部”创建。

CLU不进行隐式类型转换。在聚类中，显式类型转换`up`和`down`在抽象类型和表示之间进行变更。有一个全体类型`any`，和一个过程`force[]`来检查一个对象是否是一个特定类型。对象可以是可变的或不可变的，后者是基础类型，比如整数、布尔值、字符和字符串。

## 其他特征

CLU类型系统的另一个关键特征是迭代器，它一个接一个的按顺序的从一个搜集返回对象。迭代器提供了一致的应用编程接口（API），而不管所用于的是什么数据。因此针对`complex_number`搜集的迭代器，与针对`integer`数组的迭代器，可以互换使用。CLU迭代器的显著特征是它们被实现为协程，每个值都是通过`yield`语句提供给调用者的。像CLU中这样的迭代器，现在是很多现代语言比如C#、Ruby和Python的常见特征，然而它们近来经常被称为生成器。下面是迭代器的例子：

```
<span style="color:darkcyan;">% 产生从1到n的奇数</span>
odds = <span style="color:green;font-weight: bold;">iter</span>(n:<span style="color:brown;">int</span>) <span style="color:green;font-weight: bold;">yields</span> <span style="color:brown;">int</span>
    i:<span style="color:brown;">int</span>
    i = 1
    <span style="color:green;font-weight: bold;">while</span> i < n <span style="color:green;font-weight: bold;">do</span>
        <span style="color:green;font-weight: bold;">yield</span> i
        i := i + 2
    <span style="color:green;font-weight: bold;">end</span>
<span style="color:green;font-weight: bold;">end</span> odds  
<span> </span>
<span style="color:green;font-weight: bold;">for</span> i:<span style="color:brown;">int</span> <span style="color:green;font-weight: bold;">in</span> odds(13) <span style="color:green;font-weight: bold;">do</span>
    print int$unparse(i) || "\n"
<span style="color:green;font-weight: bold;">end</span>
```

CLU还包括了异常处理，它参考了在其他语言中的各种尝试；异常使用`signal`引发，并通过`except`处理。不同于具有异常处理的多数其他语言，异常不会被隐式的沿着调用链重新发起。不同之处还有，在CLU中异常被当作是正常执行流程的一部分，并作为“正常”而有效的一种类型安全的方式，用来退出循环或从函数返回；这种方式下，“除非”其他条件适用，可以直接指定返回值。既未捕获也未显式的重新发起的异常，被立即转换成特殊失败异常，这典型的会终止程序。

CLU经常被引证为具有类型安全的可变类型的第一个语言，在这里叫作`oneof`，早于ML语言拥有的叫做代数数据类型的标签联合。

CLU中最后一个显著特征是并行赋值（多赋值），这里多于一个变量可以出现在赋值算符的左侧。例如，书写`x,y := y,x`将交换`x`和`y`的值。以相同的方式，函数可以返回多个值，比如`x,y,z := f(t)`。并行赋值（但未包括多返回值），在CLU之前已经出现在CPL（1963年）之中，叫作“同时赋值”，然而确是CLU使之流行，并被引证为对后来语言中出现的并行赋值有直接的影响。

在CLU程序中所有对象都存活在堆中，而内存管理是自动化的。

CLU支持参数化类型的用户定义数据抽象。它是提供类型安全限定的参数化类型的第一个语言，它使用`where`子句结构，来表达在实际类型实际参数上的约束。

## 影响

CLU和Ada是C++的模板的主要启发者。

CLU的异常处理机制影响了后来的语言如C++和Java。

Sather、Python和C#所包含的迭代器，最早出现在CLU中。

Perl和Lua采用的多赋值和从函数调用返回多个值来自CLU。

Python和Ruby从它引入了传共享调用、`yield`语句和多赋值。

## 外部链接

- www.pmg.lcs.mit.edu/CLU.html
- A History of CLU (pdf)
- clu2c: a program to compile CLU code to C
- Dictionary of Programming Languages
- CLU comparison at '99 bottles of beer' multi-language demo algorithm site

## 基本资料

- 编程范型：多范型: 面向对象, 过程式
- 发行日期：1975年
- 设计者：芭芭拉·利斯科夫和她的学生
- 开发者：麻省理工学院
- 软件版本周期：Native CLU 1.5 (SPARC, VAX) / 1989年5月26日、Portable CLU / 2009年11月6日
- 类型系统：强类型
- 软件实现：Native CLU, Portable CLU, clu2c
- 受影响于：ALGOL 60, Lisp, Simula
- 施影响于：Ada, Argus, C++, Lua, Python, Ruby, Sather, Swift