CLU是一门编程语言,由芭芭拉·利斯科夫和她的学生在1974年到1975年于麻省理工学院(MIT)创造。虽然它没有被广泛使用,但它引入了抽象数据类型[8],和许多现在广泛使用的特性,而被视为面向对象编程发展的重要一步。
Quick Facts 编程范型, 设计者 ...
CLU编程范型 | 多范型: 面向对象, 过程式 |
---|
设计者 | 芭芭拉·利斯科夫和她的学生 |
---|
实作者 | 麻省理工学院 |
---|
发行时间 | 1975年,49年前(1975) |
---|
型态系统 | 强类型 |
---|
网站 | www.pmg.lcs.mit.edu/CLU.html |
---|
|
Native CLU[1], Portable CLU[2], clu2c[3] |
|
ALGOL 60, Lisp[4], Simula[5] |
|
Ada, Argus, C++, Lua, Python[6], Ruby, Sather, Swift[7] |
Close
主要贡献还包括:传共享调用、迭代器、多值返回(并行赋值形式)、参数化类型和可变类型。值得注意的是它使用了具有构造器和方法的类,但没有继承。
CLU的语法基于了ALGOL,这是当时多数新语言设计的起点。关键增补是“聚类”(cluster)概念,它是CLU的类型扩展系统和语言名字的根源(CLUster)[9]。聚类一般对应于面向对象语言中“类”(class)的概念。例如,下面是CLU用来实现复数的语法:
complex_number = cluster is add, subtract, multiply, ...
rep = record [ real_part: real, imag_part: real ]
add = proc ... end add;
subtract = proc ... end subtract;
multiply = proc ... end multiply;
...
end complex_number;
聚类是一个模块,它封装了除了那些在is
子句中显式命名的成员之外的所有成员。这些成员对应于现在面向对象语言中一个类的公开成员。聚类还定义了可以在聚类之外引用名字的一个类型(在这个案例中是complex_number
),但是它的表示类型(这里的rep
)对于外部客户是隐藏的。
聚类名字是全局的,不提供名字空间机制来组织聚类,也不允许它们在其他聚类内部被“局部”创建。
CLU不进行隐式类型转换。在聚类中,显式类型转换up
和down
在抽象类型和表示之间进行变更。有一个全体类型any
,和一个过程force[]
来检查一个对象是否是一个特定类型。对象可以是可变的或不可变的,后者是基础类型,比如整数、布尔值、字符和字符串[9]。
CLU类型系统的另一个关键特征是迭代器,它一个接一个的按顺序的从一个搜集返回对象[9]。迭代器提供了一致的应用编程接口(API),而不管所用于的是什么数据。因此针对complex_number
搜集的迭代器,与针对integer
数组的迭代器,可以互换使用。CLU迭代器的显著特征是它们被实现为协程,每个值都是通过yield
语句提供给调用者的。像CLU中这样的迭代器,现在是很多现代语言比如C#、Ruby和Python的常见特征,然而它们近来经常被称为生成器。下面是迭代器的例子:
% 产生从1到n的奇数
odds = iter(n:int) yields int
i:int
i = 1
while i < n do
yield i
i := i + 2
end
end odds
for i:int in odds(13) do
print int$unparse(i) || "\n"
end
CLU还包括了异常处理,它参考了在其他语言中的各种尝试;异常使用signal
引发,并通过except
处理。不同于具有异常处理的多数其他语言,异常不会被隐式的沿着调用链重新发起。不同之处还有,在CLU中异常被当作是正常执行流程的一部分,并作为“正常”而有效的一种类型安全的方式,用来退出循环或从函数返回;这种方式下,“除非”其他条件适用,可以直接指定返回值。既未捕获也未显式的重新发起的异常,被立即转换成特殊失败异常,这典型的会终止程序。
CLU经常被引证为具有类型安全的可变类型的第一个语言,在这里叫作oneof
,早于ML语言拥有的叫做代数数据类型的标签联合。
CLU中最后一个显著特征是并行赋值(多赋值),这里多于一个变量可以出现在赋值算符的左侧。例如,书写x,y := y,x
将交换x
和y
的值。以相同的方式,函数可以返回多个值,比如x,y,z := f(t)
。并行赋值(但未包括多返回值),在CLU之前已经出现在CPL(1963年)之中,叫作“同时赋值”[10],然而确是CLU使之流行,并被引证为对后来语言中出现的并行赋值有直接的影响。
在CLU程序中所有对象都存活在堆中,而内存管理是自动化的。
CLU支持参数化类型的用户定义数据抽象。它是提供类型安全限定的参数化类型的第一个语言,它使用where
子句结构,来表达在实际类型实际参数上的约束。
CLU和Ada是C++的模板的主要启发者[11]。
CLU的异常处理机制影响了后来的语言如C++和Java[12]。
Sather、Python和C#所包含的迭代器,最早出现在CLU中。
Perl和Lua采用的多赋值和从函数调用返回多个值来自CLU[13]。
Python和Ruby从它引入了传共享调用、yield
语句[14]和多赋值[15]。
Curtis, Dorothy. CLU home page. Programming Methodology Group, Computer Science and Artificial Intelligence Laboratory. Massachusetts Institute of Technology. 2009-11-06 [2016-05-26]. (原始内容存档于2016-06-02).
Curtis, Dorothy. Index of /pub/pclu. Programming Methodology Group, Computer Science and Artificial Intelligence Laboratory. Massachusetts Institute of Technology. 2009-11-06 [2016-05-26].
Ushijima, Tetsu. clu2c. clu2c. woodsheep.jp. [2016-05-26]. (原始内容存档于2016-03-04).
Barbara Liskov. A history of CLU (PDF). 1992 [2022-04-27]. (原始内容 (PDF)存档于2021-11-05). CLU looks like an Algol-like language, but its semantics is like that of Lisp: CLU objects reside in an object universe (or heap), and a variable just identifies (or refers to) an object. We decided early on to have objects in the heap, although we had numerous discussions about the cost of garbage collection. This decision greatly simplified the data abstraction mechanism ……. A language that allocates objects only on the stack is not sufficiently expressive; the heap is needed for objects whose sizes must change and for objects whose lifetime exceeds that of the procedure that creates them. …… Therefore, the choice is: just heap, or both. ……
One unusual aspect of CLU is that our procedures have no free (global) variables ……. The view of procedures in CLU is similar to that in Lisp: CLU procedures are not nested (except that there can be local procedures within a cluster) but instead are defined at the "top" level, and can be called from any other module. In Lisp such procedures can have free variables that are scoped dynamically, a well-known source of confusion.
Barbara Liskov. A history of CLU (PDF). 1992 [2022-04-27]. (原始内容 (PDF)存档于2021-11-05). Programming languages that existed when the concept of data abstraction arose did not support abstract data types, but some languages contained constructs that were precursors of this notion. …… The mechanism that matched the best was the class mechanism of Simula 67. A Simula class groups a set of procedures with some variables. A class can be instantiated to provide an object containing its own copies of the variables; the class contains code that initializes these variables at instantiation time. However, Simula classes did not enforce encapsulation ……, and Simula was lacking several other features needed to support data abstraction, …….
Lundh, Fredrik. Call By Object. effbot.org. [21 November 2017]. (原始内容存档于2019-11-23). replace "CLU" with "Python", "record" with "instance", and "procedure" with "function or method", and you get a pretty accurate description of Python's object model.
Lattner, Chris. Chris Lattner's Homepage. Chris Lattner. 2014-06-03 [2014-06-03]. (原始内容存档于2018-12-25). The Swift language is the product of tireless effort from a team of language experts, documentation gurus, compiler optimization ninjas, and an incredibly important internal dogfooding group who provided feedback to help refine and battle-test ideas. Of course, it also greatly benefited from the experiences hard-won by many other languages in the field, drawing ideas from Objective-C, Rust, Haskell, Ruby, Python, C#, CLU, and far too many others to list.
Ruby's Roots and Matz's Leadership. Appfolio Engineering. 2019-11-08 [2019-11-15]. (原始内容存档于2019-11-14). Matz feels that blocks are the greatest invention of Ruby (I agree.) He got the idea from a 1970s language called CLU from MIT, which called them 'iterators'...